ai-parrot 0.3.4__cp311-cp311-manylinux_2_17_x86_64.manylinux2014_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.
- ai_parrot-0.3.4.dist-info/LICENSE +21 -0
- ai_parrot-0.3.4.dist-info/METADATA +319 -0
- ai_parrot-0.3.4.dist-info/RECORD +109 -0
- ai_parrot-0.3.4.dist-info/WHEEL +6 -0
- ai_parrot-0.3.4.dist-info/top_level.txt +3 -0
- parrot/__init__.py +21 -0
- parrot/chatbots/__init__.py +7 -0
- parrot/chatbots/abstract.py +728 -0
- parrot/chatbots/asktroc.py +16 -0
- parrot/chatbots/base.py +366 -0
- parrot/chatbots/basic.py +9 -0
- parrot/chatbots/bose.py +17 -0
- parrot/chatbots/cody.py +17 -0
- parrot/chatbots/copilot.py +83 -0
- parrot/chatbots/dataframe.py +103 -0
- parrot/chatbots/hragents.py +15 -0
- parrot/chatbots/odoo.py +17 -0
- parrot/chatbots/retrievals/__init__.py +578 -0
- parrot/chatbots/retrievals/constitutional.py +19 -0
- parrot/conf.py +110 -0
- parrot/crew/__init__.py +3 -0
- parrot/crew/tools/__init__.py +22 -0
- parrot/crew/tools/bing.py +13 -0
- parrot/crew/tools/config.py +43 -0
- parrot/crew/tools/duckgo.py +62 -0
- parrot/crew/tools/file.py +24 -0
- parrot/crew/tools/google.py +168 -0
- parrot/crew/tools/gtrends.py +16 -0
- parrot/crew/tools/md2pdf.py +25 -0
- parrot/crew/tools/rag.py +42 -0
- parrot/crew/tools/search.py +32 -0
- parrot/crew/tools/url.py +21 -0
- parrot/exceptions.cpython-311-x86_64-linux-gnu.so +0 -0
- parrot/handlers/__init__.py +4 -0
- parrot/handlers/bots.py +196 -0
- parrot/handlers/chat.py +162 -0
- parrot/interfaces/__init__.py +6 -0
- parrot/interfaces/database.py +29 -0
- parrot/llms/__init__.py +137 -0
- parrot/llms/abstract.py +47 -0
- parrot/llms/anthropic.py +42 -0
- parrot/llms/google.py +42 -0
- parrot/llms/groq.py +45 -0
- parrot/llms/hf.py +45 -0
- parrot/llms/openai.py +59 -0
- parrot/llms/pipes.py +114 -0
- parrot/llms/vertex.py +78 -0
- parrot/loaders/__init__.py +20 -0
- parrot/loaders/abstract.py +456 -0
- parrot/loaders/audio.py +106 -0
- parrot/loaders/basepdf.py +102 -0
- parrot/loaders/basevideo.py +280 -0
- parrot/loaders/csv.py +42 -0
- parrot/loaders/dir.py +37 -0
- parrot/loaders/excel.py +349 -0
- parrot/loaders/github.py +65 -0
- parrot/loaders/handlers/__init__.py +5 -0
- parrot/loaders/handlers/data.py +213 -0
- parrot/loaders/image.py +119 -0
- parrot/loaders/json.py +52 -0
- parrot/loaders/pdf.py +437 -0
- parrot/loaders/pdfchapters.py +142 -0
- parrot/loaders/pdffn.py +112 -0
- parrot/loaders/pdfimages.py +207 -0
- parrot/loaders/pdfmark.py +88 -0
- parrot/loaders/pdftables.py +145 -0
- parrot/loaders/ppt.py +30 -0
- parrot/loaders/qa.py +81 -0
- parrot/loaders/repo.py +103 -0
- parrot/loaders/rtd.py +65 -0
- parrot/loaders/txt.py +92 -0
- parrot/loaders/utils/__init__.py +1 -0
- parrot/loaders/utils/models.py +25 -0
- parrot/loaders/video.py +96 -0
- parrot/loaders/videolocal.py +120 -0
- parrot/loaders/vimeo.py +106 -0
- parrot/loaders/web.py +216 -0
- parrot/loaders/web_base.py +112 -0
- parrot/loaders/word.py +125 -0
- parrot/loaders/youtube.py +192 -0
- parrot/manager.py +166 -0
- parrot/models.py +372 -0
- parrot/py.typed +0 -0
- parrot/stores/__init__.py +48 -0
- parrot/stores/abstract.py +171 -0
- parrot/stores/milvus.py +632 -0
- parrot/stores/qdrant.py +153 -0
- parrot/tools/__init__.py +12 -0
- parrot/tools/abstract.py +53 -0
- parrot/tools/asknews.py +32 -0
- parrot/tools/bing.py +13 -0
- parrot/tools/duck.py +62 -0
- parrot/tools/google.py +170 -0
- parrot/tools/stack.py +26 -0
- parrot/tools/weather.py +70 -0
- parrot/tools/wikipedia.py +59 -0
- parrot/tools/zipcode.py +179 -0
- parrot/utils/__init__.py +2 -0
- parrot/utils/parsers/__init__.py +5 -0
- parrot/utils/parsers/toml.cpython-311-x86_64-linux-gnu.so +0 -0
- parrot/utils/toml.py +11 -0
- parrot/utils/types.cpython-311-x86_64-linux-gnu.so +0 -0
- parrot/utils/uv.py +11 -0
- parrot/version.py +10 -0
- resources/users/__init__.py +5 -0
- resources/users/handlers.py +13 -0
- resources/users/models.py +205 -0
- settings/__init__.py +0 -0
- settings/settings.py +51 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from parrot.chatbots import Chatbot
|
|
2
|
+
|
|
3
|
+
class AskTROC(Chatbot):
|
|
4
|
+
"""Represents an Human Resources agent in Navigator.
|
|
5
|
+
|
|
6
|
+
Each agent has a name, a role, a goal, a backstory,
|
|
7
|
+
and an optional language model (llm).
|
|
8
|
+
"""
|
|
9
|
+
company_information: dict = {
|
|
10
|
+
'company': 'T-ROC Global',
|
|
11
|
+
'company_website': 'https://www.trocglobal.com',
|
|
12
|
+
'contact_email': 'communications@trocglobal.com',
|
|
13
|
+
'contact_form': 'https://www.surveymonkey.com/r/TROC_Suggestion_Box'
|
|
14
|
+
}
|
|
15
|
+
role: str = 'Expert T-ROCer'
|
|
16
|
+
goal = 'Bring useful information about T-ROC Global to employees.'
|
parrot/chatbots/base.py
ADDED
|
@@ -0,0 +1,366 @@
|
|
|
1
|
+
from abc import ABC
|
|
2
|
+
from typing import Any
|
|
3
|
+
from aiohttp import web
|
|
4
|
+
# Langchain:
|
|
5
|
+
from langchain_core.prompts import (
|
|
6
|
+
PromptTemplate,
|
|
7
|
+
ChatPromptTemplate
|
|
8
|
+
)
|
|
9
|
+
from langchain.agents.agent import (
|
|
10
|
+
AgentExecutor,
|
|
11
|
+
RunnableAgent,
|
|
12
|
+
RunnableMultiActionAgent,
|
|
13
|
+
)
|
|
14
|
+
from langchain.memory import (
|
|
15
|
+
ConversationBufferMemory
|
|
16
|
+
)
|
|
17
|
+
from langchain.agents import create_react_agent
|
|
18
|
+
from langchain_community.chat_message_histories import (
|
|
19
|
+
RedisChatMessageHistory
|
|
20
|
+
)
|
|
21
|
+
from navconfig.logging import logging
|
|
22
|
+
## LLM configuration
|
|
23
|
+
# Vertex
|
|
24
|
+
try:
|
|
25
|
+
from ..llms.vertex import VertexLLM
|
|
26
|
+
VERTEX_ENABLED = True
|
|
27
|
+
except (ModuleNotFoundError, ImportError):
|
|
28
|
+
VERTEX_ENABLED = False
|
|
29
|
+
|
|
30
|
+
# Google
|
|
31
|
+
try:
|
|
32
|
+
from ..llms.google import GoogleGenAI
|
|
33
|
+
GOOGLE_ENABLED = True
|
|
34
|
+
except (ModuleNotFoundError, ImportError):
|
|
35
|
+
GOOGLE_ENABLED = False
|
|
36
|
+
|
|
37
|
+
# Anthropic:
|
|
38
|
+
try:
|
|
39
|
+
from ..llms.anthropic import Anthropic
|
|
40
|
+
ANTHROPIC_ENABLED = True
|
|
41
|
+
except (ModuleNotFoundError, ImportError):
|
|
42
|
+
ANTHROPIC_ENABLED = False
|
|
43
|
+
|
|
44
|
+
# OpenAI
|
|
45
|
+
try:
|
|
46
|
+
from ..llms.openai import OpenAILLM
|
|
47
|
+
OPENAI_ENABLED = True
|
|
48
|
+
except (ModuleNotFoundError, ImportError):
|
|
49
|
+
OPENAI_ENABLED = False
|
|
50
|
+
|
|
51
|
+
# Groq
|
|
52
|
+
try:
|
|
53
|
+
from ..llms.groq import GroqLLM
|
|
54
|
+
GROQ_ENABLED = True
|
|
55
|
+
except (ModuleNotFoundError, ImportError):
|
|
56
|
+
GROQ_ENABLED = False
|
|
57
|
+
|
|
58
|
+
from tenacity import (
|
|
59
|
+
retry,
|
|
60
|
+
stop_after_attempt,
|
|
61
|
+
wait_random_exponential,
|
|
62
|
+
) # for exponential backoff
|
|
63
|
+
from ..interfaces import DBInterface
|
|
64
|
+
from ..models import AgentResponse
|
|
65
|
+
from ..conf import REDIS_HISTORY_URL
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
BASEPROMPT = """
|
|
69
|
+
Your name is {name}. You are a helpful and advanced AI assistant equipped with various tools to help users find information and solve problems efficiently.
|
|
70
|
+
You are designed to be able to assist with a wide range of tasks.
|
|
71
|
+
Overall, Assistant is a powerful tool that can help with a wide range of tasks and provide valuable insights and information on a wide range of topics.
|
|
72
|
+
Whether you need help with a specific question or just want to have a conversation about a particular topic, Assistant is here to assist.
|
|
73
|
+
|
|
74
|
+
**Has access to the following tools:**
|
|
75
|
+
|
|
76
|
+
- {tools}
|
|
77
|
+
- Google Web Search: Perform web searches to retrieve the latest and most relevant information from the internet.
|
|
78
|
+
- google_maps_location_finder: Find location information, including latitude, longitude, and other geographical details.
|
|
79
|
+
- Wikipedia: Access detailed and verified information from Wikipedia.
|
|
80
|
+
- WikiData: Fetch structured data from WikiData for precise and factual details.
|
|
81
|
+
- Bing Search: Search the web using Microsoft Bing Search, conduct searches using Bing for alternative perspectives and sources.
|
|
82
|
+
- DuckDuckGo Web Search: Search the web using DuckDuckGo Search.
|
|
83
|
+
- zipcode_distance: Calculate the distance between two zip codes.
|
|
84
|
+
- zipcode_location: Obtain geographical information about a specific zip code.
|
|
85
|
+
- zipcodes_by_radius: Find all US zip codes within a given radius of a zip code.
|
|
86
|
+
- asknews_search: Search for up-to-date news and historical news on AskNews site.
|
|
87
|
+
- StackExchangeSearch: Search for questions and answers on Stack Exchange.
|
|
88
|
+
- openweather_tool: Get current weather conditions based on specific location, providing latitude and longitude.
|
|
89
|
+
- OpenWeatherMap: Get weather information about a location.
|
|
90
|
+
- yahoo_finance_news: Retrieve the latest financial news from Yahoo Finance.
|
|
91
|
+
- python_repl_ast: A Python shell. Use this to execute python commands. Input should be a valid python command. When using this tool, sometimes output is abbreviated - make sure it does not look abbreviated before using it in your answer.
|
|
92
|
+
- youtube_search: Search for videos on YouTube based on specific keywords.
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
Use these tools effectively to provide accurate and comprehensive responses.
|
|
96
|
+
|
|
97
|
+
**Instructions:**
|
|
98
|
+
1. Understand the Query: Comprehend the user's request, especially if it pertains to events that may have already happened.
|
|
99
|
+
2. **Event Timing Validation**: For questions about recent events or events that may have happened already (like sporting events, conferences, etc.), if you're not confident that the event has happened, you must **use one of the web search tools** to confirm before making any conclusions.
|
|
100
|
+
3. Determine Confidence: If confident (90%+), provide the answer directly within the Thought process. If not confident, **always use a web search tool**.
|
|
101
|
+
4. Choose Tool: If needed, select the most suitable tool, using one of [{tool_names}].
|
|
102
|
+
5. Collect Information: Use the tool to gather data.
|
|
103
|
+
6. Analyze Information: Identify patterns, relationships, and insights.
|
|
104
|
+
7. Synthesize Response: Combine the information into a clear response.
|
|
105
|
+
8. Cite Sources: Mention the sources of the information.
|
|
106
|
+
|
|
107
|
+
** Your Style: **
|
|
108
|
+
- Maintain a professional and friendly tone.
|
|
109
|
+
- Be clear and concise in your explanations.
|
|
110
|
+
- Use simple language for complex topics to ensure user understanding.
|
|
111
|
+
|
|
112
|
+
To respond directly, use the following format:
|
|
113
|
+
```
|
|
114
|
+
Question: the input question you must answer.
|
|
115
|
+
Thought: Explain your reasoning.
|
|
116
|
+
Final Thought: Summarize your findings.
|
|
117
|
+
Final Answer: Provide a clear and structured answer to the original question with relevant details.
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
To use a tool, please use the following format:
|
|
122
|
+
```
|
|
123
|
+
Question: the input question you must answer.
|
|
124
|
+
Thought: Explain your reasoning, including whether you need to use a tool.
|
|
125
|
+
Action: the action to take, should be one of [{tool_names}].
|
|
126
|
+
- If using a tool: Specify the tool name (e.g., "Google Web Search") and the input.
|
|
127
|
+
Action Input: the input to the action.
|
|
128
|
+
Observation: the result of the action.
|
|
129
|
+
... (this Thought/Action/Action Input/Observation can repeat N times)
|
|
130
|
+
Final Thought: Summarize your findings.
|
|
131
|
+
Final Answer: Provide a clear and structured answer to the original question with relevant details.
|
|
132
|
+
Detailed Result: Include the detailed result from the tool here if applicable.
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
**Important**: For recent events (such as the Paris 2024 Olympic Games), you must **use a web search tool** to verify the outcome or provide accurate up-to-date information before concluding. Always prioritize using tools if you're unsure or if the event is recent.
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
Begin!
|
|
139
|
+
|
|
140
|
+
Question: {input}
|
|
141
|
+
{agent_scratchpad}
|
|
142
|
+
"""
|
|
143
|
+
|
|
144
|
+
class BaseAgent(ABC, DBInterface):
|
|
145
|
+
"""Base Agent Interface.
|
|
146
|
+
|
|
147
|
+
This is the base class for all Agent Chatbots. It is an abstract class that
|
|
148
|
+
must be implemented by all Agent Chatbots.
|
|
149
|
+
|
|
150
|
+
"""
|
|
151
|
+
def __init__(
|
|
152
|
+
self,
|
|
153
|
+
name: str = 'Agent',
|
|
154
|
+
llm: str = 'vertexai',
|
|
155
|
+
tools: list = None,
|
|
156
|
+
prompt_template: str = None,
|
|
157
|
+
**kwargs
|
|
158
|
+
):
|
|
159
|
+
self.name = name
|
|
160
|
+
self.tools = tools
|
|
161
|
+
self.prompt_template = prompt_template
|
|
162
|
+
if not self.prompt_template:
|
|
163
|
+
self.prompt_template = BASEPROMPT
|
|
164
|
+
self.llm = self.llm_chain(llm, **kwargs)
|
|
165
|
+
self.prompt = self.get_prompt(self.prompt_template)
|
|
166
|
+
self.kwargs = kwargs
|
|
167
|
+
# Bot:
|
|
168
|
+
self._agent = None
|
|
169
|
+
self.agent = None
|
|
170
|
+
# Logger:
|
|
171
|
+
self.logger = logging.getLogger('Parrot.Agent')
|
|
172
|
+
|
|
173
|
+
def get_prompt(self, prompt, **kwargs):
|
|
174
|
+
partial_prompt = ChatPromptTemplate.from_template(prompt)
|
|
175
|
+
return partial_prompt.partial(
|
|
176
|
+
tools=self.tools,
|
|
177
|
+
name=self.name,
|
|
178
|
+
**kwargs
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
def get_memory(
|
|
182
|
+
self,
|
|
183
|
+
session_id: str = None,
|
|
184
|
+
key: str = 'chat_history',
|
|
185
|
+
input_key: str = 'question',
|
|
186
|
+
output_key: str = 'answer',
|
|
187
|
+
size: int = 5,
|
|
188
|
+
ttl: int = 86400
|
|
189
|
+
):
|
|
190
|
+
args = {
|
|
191
|
+
'memory_key': key,
|
|
192
|
+
'input_key': input_key,
|
|
193
|
+
'output_key': output_key,
|
|
194
|
+
'return_messages': True,
|
|
195
|
+
'max_len': size
|
|
196
|
+
}
|
|
197
|
+
if session_id:
|
|
198
|
+
message_history = RedisChatMessageHistory(
|
|
199
|
+
url=REDIS_HISTORY_URL,
|
|
200
|
+
session_id=session_id,
|
|
201
|
+
ttl=ttl
|
|
202
|
+
)
|
|
203
|
+
args['chat_memory'] = message_history
|
|
204
|
+
return ConversationBufferMemory(
|
|
205
|
+
**args
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
def create_agent(self, **kwargs):
|
|
209
|
+
# Create a ReAct Agent:
|
|
210
|
+
self.agent = RunnableAgent(
|
|
211
|
+
runnable = create_react_agent(
|
|
212
|
+
self.llm,
|
|
213
|
+
self.tools,
|
|
214
|
+
prompt=self.prompt,
|
|
215
|
+
), # type: ignore
|
|
216
|
+
input_keys_arg=["input"],
|
|
217
|
+
return_keys_arg=["output"],
|
|
218
|
+
)
|
|
219
|
+
return self.agent
|
|
220
|
+
|
|
221
|
+
@retry(wait=wait_random_exponential(min=1, max=60), stop=stop_after_attempt(6))
|
|
222
|
+
def llm_chain(
|
|
223
|
+
self, llm: str = "vertexai", **kwargs
|
|
224
|
+
):
|
|
225
|
+
"""llm_chain.
|
|
226
|
+
|
|
227
|
+
Args:
|
|
228
|
+
llm (str): The language model to use.
|
|
229
|
+
|
|
230
|
+
Returns:
|
|
231
|
+
str: The language model to use.
|
|
232
|
+
|
|
233
|
+
"""
|
|
234
|
+
if llm == 'openai':
|
|
235
|
+
mdl = OpenAILLM(model="gpt-3.5-turbo", **kwargs)
|
|
236
|
+
elif llm in ('vertexai', 'VertexLLM'):
|
|
237
|
+
mdl = VertexLLM(model="gemini-1.5-pro", **kwargs)
|
|
238
|
+
elif llm == 'anthropic':
|
|
239
|
+
mdl = Anthropic(model="claude-3-opus-20240229", **kwargs)
|
|
240
|
+
elif llm in ('groq', 'Groq', 'llama3'):
|
|
241
|
+
mdl = GroqLLM(model="llama3-70b-8192", **kwargs)
|
|
242
|
+
elif llm == 'mixtral':
|
|
243
|
+
mdl = GroqLLM(model="mixtral-8x7b-32768", **kwargs)
|
|
244
|
+
elif llm == 'google':
|
|
245
|
+
mdl = GoogleGenAI(model="models/gemini-1.5-pro-latest", **kwargs)
|
|
246
|
+
else:
|
|
247
|
+
raise ValueError(f"Invalid llm: {llm}")
|
|
248
|
+
|
|
249
|
+
# get the LLM:
|
|
250
|
+
return mdl.get_llm()
|
|
251
|
+
|
|
252
|
+
def get_executor(self, agent: RunnableAgent, tools: list, verbose: bool = True):
|
|
253
|
+
return AgentExecutor(
|
|
254
|
+
agent=agent,
|
|
255
|
+
tools=tools,
|
|
256
|
+
# callback_manager=callback_manager,
|
|
257
|
+
verbose=verbose,
|
|
258
|
+
return_intermediate_steps=True,
|
|
259
|
+
max_iterations=5,
|
|
260
|
+
max_execution_time=360,
|
|
261
|
+
handle_parsing_errors=True,
|
|
262
|
+
# memory=self.memory,
|
|
263
|
+
# early_stopping_method='generate',
|
|
264
|
+
**(self.kwargs or {}),
|
|
265
|
+
)
|
|
266
|
+
|
|
267
|
+
def get_chatbot(self):
|
|
268
|
+
return self.get_executor(self.agent, self.tools)
|
|
269
|
+
|
|
270
|
+
def __enter__(self):
|
|
271
|
+
return self
|
|
272
|
+
|
|
273
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
274
|
+
self._agent = None
|
|
275
|
+
|
|
276
|
+
def get_conversation(self):
|
|
277
|
+
# Create the agent:
|
|
278
|
+
self.create_agent()
|
|
279
|
+
# define conversation:
|
|
280
|
+
self._agent = self.get_chatbot()
|
|
281
|
+
return self
|
|
282
|
+
|
|
283
|
+
def get_retrieval(self, request: web.Request) -> Any:
|
|
284
|
+
# Create the agent:
|
|
285
|
+
self.create_agent()
|
|
286
|
+
# define conversation:
|
|
287
|
+
self._agent = self.get_chatbot()
|
|
288
|
+
self.request = request
|
|
289
|
+
return self
|
|
290
|
+
|
|
291
|
+
async def question(
|
|
292
|
+
self,
|
|
293
|
+
question: str = None,
|
|
294
|
+
chain_type: str = 'stuff',
|
|
295
|
+
search_type: str = 'similarity',
|
|
296
|
+
search_kwargs: dict = {"k": 4, "fetch_k": 10, "lambda_mult": 0.89},
|
|
297
|
+
return_docs: bool = True,
|
|
298
|
+
metric_type: str = None,
|
|
299
|
+
memory: Any = None,
|
|
300
|
+
**kwargs
|
|
301
|
+
):
|
|
302
|
+
"""question.
|
|
303
|
+
|
|
304
|
+
Args:
|
|
305
|
+
question (str): The question to ask the chatbot.
|
|
306
|
+
chain_type (str): The type of chain to use.
|
|
307
|
+
search_type (str): The type of search to use.
|
|
308
|
+
search_kwargs (dict): The search kwargs to use.
|
|
309
|
+
return_docs (bool): Return the documents.
|
|
310
|
+
metric_type (str): The metric type to use.
|
|
311
|
+
memory (Any): The memory to use.
|
|
312
|
+
|
|
313
|
+
Returns:
|
|
314
|
+
Any: The response from the chatbot.
|
|
315
|
+
|
|
316
|
+
"""
|
|
317
|
+
# TODO: adding the vector-search to the agent
|
|
318
|
+
input_question = {
|
|
319
|
+
"input": question
|
|
320
|
+
}
|
|
321
|
+
result = self._agent.invoke(input_question)
|
|
322
|
+
try:
|
|
323
|
+
response = AgentResponse(question=question, **result)
|
|
324
|
+
response.response = self.as_markdown(
|
|
325
|
+
response
|
|
326
|
+
)
|
|
327
|
+
return response
|
|
328
|
+
except Exception as e:
|
|
329
|
+
self.logger.exception(
|
|
330
|
+
f"Error on response: {e}"
|
|
331
|
+
)
|
|
332
|
+
raise
|
|
333
|
+
|
|
334
|
+
def invoke(self, query: str):
|
|
335
|
+
"""invoke.
|
|
336
|
+
|
|
337
|
+
Args:
|
|
338
|
+
query (str): The query to ask the chatbot.
|
|
339
|
+
|
|
340
|
+
Returns:
|
|
341
|
+
str: The response from the chatbot.
|
|
342
|
+
|
|
343
|
+
"""
|
|
344
|
+
input_question = {
|
|
345
|
+
"input": query
|
|
346
|
+
}
|
|
347
|
+
result = self._agent.invoke(input_question)
|
|
348
|
+
try:
|
|
349
|
+
response = AgentResponse(question=query, **result)
|
|
350
|
+
try:
|
|
351
|
+
return self.as_markdown(
|
|
352
|
+
response
|
|
353
|
+
), response
|
|
354
|
+
except Exception as exc:
|
|
355
|
+
self.logger.exception(
|
|
356
|
+
f"Error on response: {exc}"
|
|
357
|
+
)
|
|
358
|
+
return result.get('output', None), None
|
|
359
|
+
except Exception as e:
|
|
360
|
+
return result, e
|
|
361
|
+
|
|
362
|
+
def as_markdown(self, response: AgentResponse) -> str:
|
|
363
|
+
markdown_output = f"**Question**: {response.question} \n"
|
|
364
|
+
markdown_output += f"**Answer**: {response.output} \n"
|
|
365
|
+
markdown_output += "```"
|
|
366
|
+
return markdown_output
|
parrot/chatbots/basic.py
ADDED
parrot/chatbots/bose.py
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
from .basic import Chatbot
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class BoseBot(Chatbot):
|
|
5
|
+
"""Represents an agent in Navigator.
|
|
6
|
+
https://eminent-kiwi-trusty.ngrok-free.app/api/bose/messages
|
|
7
|
+
Each agent has a name, a role, a goal, a backstory,
|
|
8
|
+
and an optional language model (llm).
|
|
9
|
+
"""
|
|
10
|
+
name: str = 'BoseBot'
|
|
11
|
+
company: str = 'T-ROC Global'
|
|
12
|
+
company_website: str = 'https://www.trocglobal.com'
|
|
13
|
+
contact_information = 'communications@trocglobal.com'
|
|
14
|
+
contact_form = 'https://bose.trocdigital.io/bose/bose_ticketing_system'
|
|
15
|
+
role: str = 'Bose Sound Systems Expert Technician and Consultant.'
|
|
16
|
+
goal = 'Bring useful information to Bose Technicians and Consultants.'
|
|
17
|
+
specialty_area = 'Bose endcap displays that are used to showcase Bose products'
|
parrot/chatbots/cody.py
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
from parrot.chatbots import Chatbot
|
|
2
|
+
|
|
3
|
+
class Cody(Chatbot):
|
|
4
|
+
"""Represents a Python expert in Navigator.
|
|
5
|
+
|
|
6
|
+
Each expert has a name, a role, a goal, a backstory,
|
|
7
|
+
and an optional language model (llm).
|
|
8
|
+
"""
|
|
9
|
+
name: str = 'Cody'
|
|
10
|
+
company_information: dict = {
|
|
11
|
+
'company': 'T-ROC Global',
|
|
12
|
+
'company_website': 'https://www.trocglobal.com',
|
|
13
|
+
'contact_email': 'communications@trocglobal.com',
|
|
14
|
+
'contact_form': 'https://www.surveymonkey.com/r/TROC_Suggestion_Box'
|
|
15
|
+
}
|
|
16
|
+
role: str = 'Python Expert'
|
|
17
|
+
goal = 'Provide useful information about Python programming to employees.'
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
from langchain_experimental.tools.python.tool import PythonAstREPLTool
|
|
2
|
+
from .base import BaseAgent
|
|
3
|
+
# importing Tools
|
|
4
|
+
from ..tools import (
|
|
5
|
+
ZipcodeAPIToolkit,
|
|
6
|
+
WikipediaTool,
|
|
7
|
+
WikidataTool,
|
|
8
|
+
GoogleSearchTool,
|
|
9
|
+
GoogleLocationFinder,
|
|
10
|
+
BingSearchTool,
|
|
11
|
+
AskNewsTool,
|
|
12
|
+
DuckDuckGoSearchTool,
|
|
13
|
+
YouTubeSearchTool,
|
|
14
|
+
OpenWeatherMapTool,
|
|
15
|
+
StackExchangeTool,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class CopilotAgent(BaseAgent):
|
|
20
|
+
"""CopilotAgent Agent.
|
|
21
|
+
|
|
22
|
+
This is Agent Base class for AI Copilots.
|
|
23
|
+
"""
|
|
24
|
+
def __init__(
|
|
25
|
+
self,
|
|
26
|
+
name: str = 'Agent',
|
|
27
|
+
llm: str = 'vertexai',
|
|
28
|
+
tools: list = None,
|
|
29
|
+
prompt_template: str = None,
|
|
30
|
+
**kwargs
|
|
31
|
+
):
|
|
32
|
+
super().__init__(name, llm, tools, prompt_template, **kwargs)
|
|
33
|
+
self.tools = [
|
|
34
|
+
PythonAstREPLTool(
|
|
35
|
+
name='python_repl_ast',
|
|
36
|
+
globals={},
|
|
37
|
+
locals={}
|
|
38
|
+
)
|
|
39
|
+
] + list(tools)
|
|
40
|
+
self.prompt = self.get_prompt(
|
|
41
|
+
self.prompt_template
|
|
42
|
+
)
|
|
43
|
+
# print('PROMPT > ', self.prompt)
|
|
44
|
+
|
|
45
|
+
@classmethod
|
|
46
|
+
def default_tools(cls) -> list:
|
|
47
|
+
# ZipCode API Toolkit
|
|
48
|
+
tools = []
|
|
49
|
+
zpt_tools = []
|
|
50
|
+
try:
|
|
51
|
+
zpt = ZipcodeAPIToolkit()
|
|
52
|
+
zpt_tools = zpt.get_tools()
|
|
53
|
+
|
|
54
|
+
except Exception as e:
|
|
55
|
+
print('ERROR LOADING ZIPCODE TOOLS')
|
|
56
|
+
|
|
57
|
+
try:
|
|
58
|
+
wk1 = WikipediaTool()
|
|
59
|
+
wk12 = WikidataTool()
|
|
60
|
+
|
|
61
|
+
g1 = GoogleSearchTool()
|
|
62
|
+
g2 = GoogleLocationFinder()
|
|
63
|
+
|
|
64
|
+
b = BingSearchTool()
|
|
65
|
+
d = DuckDuckGoSearchTool()
|
|
66
|
+
ask = AskNewsTool()
|
|
67
|
+
|
|
68
|
+
yt = YouTubeSearchTool()
|
|
69
|
+
stackexchange = StackExchangeTool()
|
|
70
|
+
weather = OpenWeatherMapTool()
|
|
71
|
+
|
|
72
|
+
tools = [
|
|
73
|
+
wk1,
|
|
74
|
+
wk12, g1, g2,
|
|
75
|
+
b, d, ask, yt,
|
|
76
|
+
weather,
|
|
77
|
+
stackexchange
|
|
78
|
+
] + zpt_tools
|
|
79
|
+
|
|
80
|
+
except Exception as e:
|
|
81
|
+
print('TOOL Error > ', e)
|
|
82
|
+
|
|
83
|
+
return tools
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
from typing import Union
|
|
2
|
+
import pandas as pd
|
|
3
|
+
from langchain_experimental.tools.python.tool import PythonAstREPLTool
|
|
4
|
+
from .base import BaseAgent
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
BASEPROMPT = """
|
|
8
|
+
Your name is {name}, You are a helpful assistant built to provide comprehensive guidance and support on data calculations and various aspects of payroll, such as earnings, deductions, salary information, and payroll tax. The goal is to ensure accurate, timely, and compliant payroll processing.
|
|
9
|
+
|
|
10
|
+
**Your Capabilities:**
|
|
11
|
+
|
|
12
|
+
1. **Earnings Calculation:**
|
|
13
|
+
- Calculate regular earnings based on hourly rates or salaries.
|
|
14
|
+
- Handle overtime calculations, including differentials and double-time as needed.
|
|
15
|
+
- Include bonuses, commissions, and other incentive earnings.
|
|
16
|
+
|
|
17
|
+
2. **Deductions:**
|
|
18
|
+
- Calculate mandatory deductions including federal, state, and local taxes.
|
|
19
|
+
- Handle other withholdings such as Social Security, Medicare, disability insurance, and unemployment insurance.
|
|
20
|
+
- Process voluntary deductions (e.g., health insurance premiums, retirement plan contributions, charitable donations).
|
|
21
|
+
|
|
22
|
+
3. **Salary Information:**
|
|
23
|
+
- Provide gross and net salary breakdowns.
|
|
24
|
+
- Assist in setting up and adjusting salary structures.
|
|
25
|
+
- Manage payroll for part-time, full-time, and contract employees.
|
|
26
|
+
|
|
27
|
+
These keywords must never be translated and transformed:
|
|
28
|
+
- Action:
|
|
29
|
+
- Thought:
|
|
30
|
+
- Action Input:
|
|
31
|
+
because they are part of the thinking process instead of the output.
|
|
32
|
+
|
|
33
|
+
You are working with {num_dfs} pandas dataframes in Python named df1, df2, etc. You should use the tools below to answer the question posed to you:
|
|
34
|
+
|
|
35
|
+
- python_repl_ast: A Python shell. Use this to execute python commands. Input should be a valid python command. When using this tool, sometimes output is abbreviated - make sure it does not look abbreviated before using it in your answer.
|
|
36
|
+
- {tools}
|
|
37
|
+
|
|
38
|
+
To use a tool, please use the following format:
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
Question: the input question you must answer.
|
|
42
|
+
Thought: You should always think about what to do, don't try to reason out the answer on your own.
|
|
43
|
+
Action: the action to take, should be one of [python_repl_ast,{tool_names}] if using a tool, otherwise answer on your own.
|
|
44
|
+
Action Input: the input to the action.
|
|
45
|
+
Observation: the result of the action.
|
|
46
|
+
... (this Thought/Action/Action Input/Observation can repeat N times)
|
|
47
|
+
Final Thought: I now know the final answer.
|
|
48
|
+
Final Answer: the final answer to the original input question.
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
This is the result of `print(df1.head())` for each dataframe:
|
|
54
|
+
{dfs_head}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Begin!
|
|
58
|
+
|
|
59
|
+
Question: {input}
|
|
60
|
+
{agent_scratchpad}
|
|
61
|
+
"""
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class DataFrameAgent(BaseAgent):
|
|
65
|
+
"""Dataframe Agent.
|
|
66
|
+
|
|
67
|
+
This is the Pandas Agent Chatbot.
|
|
68
|
+
"""
|
|
69
|
+
def __init__(
|
|
70
|
+
self,
|
|
71
|
+
name: str = 'Agent',
|
|
72
|
+
llm: str = 'vertexai',
|
|
73
|
+
tools: list = None,
|
|
74
|
+
df: Union[list[pd.DataFrame], pd.DataFrame] = None,
|
|
75
|
+
prompt_template: str = None,
|
|
76
|
+
**kwargs
|
|
77
|
+
):
|
|
78
|
+
super().__init__(name, llm, tools, prompt_template, **kwargs)
|
|
79
|
+
for _df in df if isinstance(df, list) else [df]:
|
|
80
|
+
if not isinstance(_df, pd.DataFrame):
|
|
81
|
+
raise ValueError(
|
|
82
|
+
f"Expected pandas DataFrame, got {type(_df)}"
|
|
83
|
+
)
|
|
84
|
+
self.df = df
|
|
85
|
+
df_locals = {}
|
|
86
|
+
dfs_head = ""
|
|
87
|
+
num_dfs = 1
|
|
88
|
+
if isinstance(df, pd.DataFrame):
|
|
89
|
+
df = [df]
|
|
90
|
+
num_dfs = len(df)
|
|
91
|
+
for i, dataframe in enumerate(df):
|
|
92
|
+
df_locals[f"df{i + 1}"] = dataframe
|
|
93
|
+
dfs_head += (
|
|
94
|
+
f"\n\n- This is the result of `print(df{i + 1}.head())`:\n"
|
|
95
|
+
+ dataframe.head().to_markdown() + "\n"
|
|
96
|
+
)
|
|
97
|
+
prompt_template = BASEPROMPT
|
|
98
|
+
self.tools = [PythonAstREPLTool(locals=df_locals)] + list(tools)
|
|
99
|
+
self.prompt = self.get_prompt(
|
|
100
|
+
prompt_template,
|
|
101
|
+
num_dfs=num_dfs,
|
|
102
|
+
dfs_head=dfs_head
|
|
103
|
+
)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from parrot.chatbots import Chatbot
|
|
2
|
+
|
|
3
|
+
class HRAgent(Chatbot):
|
|
4
|
+
"""Represents an Human Resources agent in Navigator.
|
|
5
|
+
|
|
6
|
+
Each agent has a name, a role, a goal, a backstory,
|
|
7
|
+
and an optional language model (llm).
|
|
8
|
+
"""
|
|
9
|
+
name: str = 'TROCers'
|
|
10
|
+
company: str = 'T-ROC Global'
|
|
11
|
+
company_website: str = 'https://www.trocglobal.com'
|
|
12
|
+
contact_information = 'communications@trocglobal.com'
|
|
13
|
+
contact_form = 'https://www.surveymonkey.com/r/TROC_Suggestion_Box'
|
|
14
|
+
role: str = 'Human Resources Assistant'
|
|
15
|
+
goal = 'Bring useful information to employees'
|
parrot/chatbots/odoo.py
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
from .basic import Chatbot
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class OddieBot(Chatbot):
|
|
5
|
+
"""Represents an agent in Navigator.
|
|
6
|
+
|
|
7
|
+
Each agent has a name, a role, a goal, a backstory,
|
|
8
|
+
and an optional language model (llm).
|
|
9
|
+
"""
|
|
10
|
+
name: str = 'Oddie'
|
|
11
|
+
company: str = 'T-ROC Global'
|
|
12
|
+
company_website: str = 'https://www.trocglobal.com'
|
|
13
|
+
contact_information = 'communications@trocglobal.com'
|
|
14
|
+
contact_form = 'https://www.surveymonkey.com/r/TROC_Suggestion_Box'
|
|
15
|
+
role = "Odoo and ERP Specialist and Odoo Programmer"
|
|
16
|
+
goal = "To provide information and support on Odoo and ERP systems, help with troubleshooting, and answer any questions you may have about any Odoo and ERP systems implementation."
|
|
17
|
+
specialty_area = 'Bring useful information about Odoo ERP, documentation, usage, samples, etc.'
|