-
Notifications
You must be signed in to change notification settings - Fork 5
/
skills.py
126 lines (98 loc) · 4.48 KB
/
skills.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import json
from council.contexts import SkillContext, ChatMessage
from council.skills import SkillBase
from council.skills.google import GoogleSearchSkill, GoogleNewsSkill
from pandasai import PandasAI
from pandasai.llm.openai import OpenAI
import constants
from retrieval import Retriever
from utils import get_filename, read_file_to_df
class DocRetrievalSkill(SkillBase):
"""Skill to retrieve documents and build context"""
def __init__(self, retriever: Retriever):
super().__init__(name="document_retrieval")
self.retriever = retriever
def execute(self, context: SkillContext) -> ChatMessage:
query = context.current.last_message.message
context = self.retriever.retrieve_docs(query)
return self.build_success_message(context)
class CustomGoogleSearchSkill(GoogleSearchSkill):
"""
A skill that performs a Google search using the reformulated query from the controller.
Based on GoogleSearchSkill: https://github.com/chain-ml/council/blob/main/council/skills/google/google_search_skill.py
"""
def execute(self, context: SkillContext) -> ChatMessage:
# Execute the skill only if the API keys required for Google Search are provided
if self.gs:
prompt = context.current.last_message
resp = self.gs.execute(query=prompt.message, nb_results=5)
response_count = len(resp)
if response_count > 0:
return self.build_success_message(
f"{self._name} {response_count} responses for {prompt.message}",
json.dumps([r.dict() for r in resp]),
)
return self.build_error_message("no response")
return self.build_error_message("API keys for Google Search not provided")
class CustomGoogleNewsSkill(GoogleNewsSkill):
"""
A skill that performs a Google News search using the reformulated query from the controller.
Based on GoogleNewsSkill: https://github.com/chain-ml/council/blob/main/council/skills/google/google_news_skill.py
"""
def execute(self, context: SkillContext) -> ChatMessage:
prompt = context.current.last_message
resp = self.gn.execute(query=prompt.message, nb_results=5)
response_count = len(resp)
if response_count > 0:
return self.build_success_message(
f"gnews {response_count} responses for {prompt.message}",
json.dumps([r.dict() for r in resp]),
)
return self.build_error_message("no response")
class GoogleAggregatorSkill(SkillBase):
"""Skill to aggregate results from Google Search and Google News"""
def __init__(
self,
):
super().__init__(name="google_aggregator")
def execute(self, context: SkillContext) -> ChatMessage:
gsearch_results = (
json.loads(context.current.last_message_from_skill("gsearch").data)
if context.current.last_message_from_skill("gsearch").is_ok
else []
)
gnews_results = (
json.loads(context.current.last_message_from_skill("gnews").data)
if context.current.last_message_from_skill("gnews").is_ok
else []
)
search_results = gsearch_results + gnews_results
context = ""
for result in search_results:
text = result.get("title", "") + " " + result.get("snippet", "") + "\n\n"
context += text
return self.build_success_message(context)
class PandasSkill(SkillBase):
"""
Skill to converse with pandas Dataframe using PandasAI.
PandasAI: https://github.com/gventuri/pandas-ai/tree/main
"""
def __init__(self, api_token, model):
super().__init__(name="pandas")
self.llm = OpenAI(api_token=api_token, model=model)
def execute(self, context: SkillContext) -> ChatMessage:
query = context.current.last_message.message
df = read_file_to_df(get_filename(constants.MARKET_DATA_DIR))
pandas_ai = PandasAI(self.llm, conversational=True)
try:
response = pandas_ai(data_frame=df, prompt=query)
if (
"Unfortunately, I was not able to answer your question, because of the following error:"
in response
):
return self.build_error_message(response)
return self.build_success_message(response)
except Exception as e:
return self.build_error_message(
f"PandasAI failed due to following error: {e}"
)