ai-parrot 0.1.0__cp311-cp311-manylinux_2_28_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 (108) hide show
  1. ai_parrot-0.1.0.dist-info/LICENSE +21 -0
  2. ai_parrot-0.1.0.dist-info/METADATA +299 -0
  3. ai_parrot-0.1.0.dist-info/RECORD +108 -0
  4. ai_parrot-0.1.0.dist-info/WHEEL +5 -0
  5. ai_parrot-0.1.0.dist-info/top_level.txt +3 -0
  6. parrot/__init__.py +18 -0
  7. parrot/chatbots/__init__.py +7 -0
  8. parrot/chatbots/abstract.py +965 -0
  9. parrot/chatbots/asktroc.py +16 -0
  10. parrot/chatbots/base.py +257 -0
  11. parrot/chatbots/basic.py +9 -0
  12. parrot/chatbots/bose.py +17 -0
  13. parrot/chatbots/cody.py +17 -0
  14. parrot/chatbots/copilot.py +100 -0
  15. parrot/chatbots/dataframe.py +103 -0
  16. parrot/chatbots/hragents.py +15 -0
  17. parrot/chatbots/oddie.py +17 -0
  18. parrot/chatbots/retrievals/__init__.py +515 -0
  19. parrot/chatbots/retrievals/constitutional.py +19 -0
  20. parrot/conf.py +108 -0
  21. parrot/crew/__init__.py +3 -0
  22. parrot/crew/tools/__init__.py +22 -0
  23. parrot/crew/tools/bing.py +13 -0
  24. parrot/crew/tools/config.py +43 -0
  25. parrot/crew/tools/duckgo.py +62 -0
  26. parrot/crew/tools/file.py +24 -0
  27. parrot/crew/tools/google.py +168 -0
  28. parrot/crew/tools/gtrends.py +16 -0
  29. parrot/crew/tools/md2pdf.py +25 -0
  30. parrot/crew/tools/rag.py +42 -0
  31. parrot/crew/tools/search.py +32 -0
  32. parrot/crew/tools/url.py +21 -0
  33. parrot/exceptions.cpython-311-x86_64-linux-gnu.so +0 -0
  34. parrot/handlers/__init__.py +4 -0
  35. parrot/handlers/bots.py +196 -0
  36. parrot/handlers/chat.py +169 -0
  37. parrot/interfaces/__init__.py +6 -0
  38. parrot/interfaces/database.py +29 -0
  39. parrot/llms/__init__.py +0 -0
  40. parrot/llms/abstract.py +41 -0
  41. parrot/llms/anthropic.py +36 -0
  42. parrot/llms/google.py +37 -0
  43. parrot/llms/groq.py +33 -0
  44. parrot/llms/hf.py +39 -0
  45. parrot/llms/openai.py +49 -0
  46. parrot/llms/pipes.py +103 -0
  47. parrot/llms/vertex.py +68 -0
  48. parrot/loaders/__init__.py +20 -0
  49. parrot/loaders/abstract.py +456 -0
  50. parrot/loaders/basepdf.py +102 -0
  51. parrot/loaders/basevideo.py +280 -0
  52. parrot/loaders/csv.py +42 -0
  53. parrot/loaders/dir.py +37 -0
  54. parrot/loaders/excel.py +349 -0
  55. parrot/loaders/github.py +65 -0
  56. parrot/loaders/handlers/__init__.py +5 -0
  57. parrot/loaders/handlers/data.py +213 -0
  58. parrot/loaders/image.py +119 -0
  59. parrot/loaders/json.py +52 -0
  60. parrot/loaders/pdf.py +187 -0
  61. parrot/loaders/pdfchapters.py +142 -0
  62. parrot/loaders/pdffn.py +112 -0
  63. parrot/loaders/pdfimages.py +207 -0
  64. parrot/loaders/pdfmark.py +88 -0
  65. parrot/loaders/pdftables.py +145 -0
  66. parrot/loaders/ppt.py +30 -0
  67. parrot/loaders/qa.py +81 -0
  68. parrot/loaders/repo.py +103 -0
  69. parrot/loaders/rtd.py +65 -0
  70. parrot/loaders/txt.py +92 -0
  71. parrot/loaders/utils/__init__.py +1 -0
  72. parrot/loaders/utils/models.py +25 -0
  73. parrot/loaders/video.py +96 -0
  74. parrot/loaders/videolocal.py +107 -0
  75. parrot/loaders/vimeo.py +106 -0
  76. parrot/loaders/web.py +216 -0
  77. parrot/loaders/web_base.py +112 -0
  78. parrot/loaders/word.py +125 -0
  79. parrot/loaders/youtube.py +192 -0
  80. parrot/manager.py +152 -0
  81. parrot/models.py +347 -0
  82. parrot/py.typed +0 -0
  83. parrot/stores/__init__.py +0 -0
  84. parrot/stores/abstract.py +170 -0
  85. parrot/stores/milvus.py +540 -0
  86. parrot/stores/qdrant.py +153 -0
  87. parrot/tools/__init__.py +16 -0
  88. parrot/tools/abstract.py +53 -0
  89. parrot/tools/asknews.py +32 -0
  90. parrot/tools/bing.py +13 -0
  91. parrot/tools/duck.py +62 -0
  92. parrot/tools/google.py +170 -0
  93. parrot/tools/stack.py +26 -0
  94. parrot/tools/weather.py +70 -0
  95. parrot/tools/wikipedia.py +59 -0
  96. parrot/tools/zipcode.py +179 -0
  97. parrot/utils/__init__.py +2 -0
  98. parrot/utils/parsers/__init__.py +5 -0
  99. parrot/utils/parsers/toml.cpython-311-x86_64-linux-gnu.so +0 -0
  100. parrot/utils/toml.py +11 -0
  101. parrot/utils/types.cpython-311-x86_64-linux-gnu.so +0 -0
  102. parrot/utils/uv.py +11 -0
  103. parrot/version.py +10 -0
  104. resources/users/__init__.py +5 -0
  105. resources/users/handlers.py +13 -0
  106. resources/users/models.py +205 -0
  107. settings/__init__.py +0 -0
  108. settings/settings.py +51 -0
@@ -0,0 +1,515 @@
1
+ from collections.abc import Callable
2
+ from typing import Any
3
+ import uuid
4
+ import asyncio
5
+ from aiohttp import web
6
+ from sentence_transformers import SentenceTransformer, util
7
+ from langchain.memory import (
8
+ ConversationSummaryMemory,
9
+ ConversationBufferMemory
10
+ )
11
+ from langchain.chains.retrieval_qa.base import RetrievalQA
12
+ from langchain.chains.conversational_retrieval.base import (
13
+ ConversationalRetrievalChain
14
+ )
15
+ from langchain.retrievers import (
16
+ EnsembleRetriever,
17
+ ContextualCompressionRetriever
18
+ )
19
+ from langchain_core.vectorstores import VectorStoreRetriever
20
+ from langchain_core.prompts import (
21
+ PromptTemplate,
22
+ ChatPromptTemplate
23
+ )
24
+ from langchain_community.retrievers import BM25Retriever
25
+ from datamodel.exceptions import ValidationError # pylint: disable=E0611
26
+ from asyncdb import AsyncDB
27
+ from navconfig.logging import logging
28
+ from navigator_session import get_session
29
+ from parrot.conf import (
30
+ BIGQUERY_CREDENTIALS,
31
+ BIGQUERY_PROJECT_ID,
32
+ BIGQUERY_DATASET
33
+ )
34
+ try:
35
+ from ...llms import VertexLLM
36
+ VERTEX_ENABLED = True
37
+ except ImportError:
38
+ VERTEX_ENABLED = False
39
+
40
+ try:
41
+ from ...llms import Anthropic
42
+ ANTHROPIC_ENABLED = True
43
+ except ImportError:
44
+ ANTHROPIC_ENABLED = False
45
+
46
+ from ...utils import SafeDict
47
+ from ...models import ChatResponse, ChatbotUsage
48
+
49
+
50
+ class RetrievalManager:
51
+ """Managing the Chain Retrieval, answers and sources.
52
+ """
53
+ def __init__(
54
+ self,
55
+ chatbot_id: uuid.UUID,
56
+ chatbot_name: str,
57
+ model: Callable,
58
+ store: Callable,
59
+ memory: ConversationBufferMemory = None,
60
+ template: str = None,
61
+ source_path: str = 'web',
62
+ request: web.Request = None,
63
+ kb: Any = None
64
+ ):
65
+ # Chatbot ID:
66
+ self.chatbot_id: uuid.UUID = chatbot_id
67
+ # Chatbot Name:
68
+ self.chatbot_name: str = chatbot_name
69
+ # Source Path:
70
+ self.source_path: str = source_path
71
+ # Vector Store
72
+ self.store = store
73
+ # Memory Manager
74
+ self.memory = memory
75
+ # LLM Model
76
+ self.model = model
77
+ # template prompt
78
+ # TODO: if none, create a basic template
79
+ self.template = template
80
+ # Knowledge-base
81
+ self.kb = kb
82
+ # Logger:
83
+ self.logger = logging.getLogger('Parrot.Retrieval')
84
+ # Web Request:
85
+ self.request = request
86
+
87
+
88
+ def __enter__(self):
89
+ self.client_id: str = str(uuid.uuid4())
90
+ self.client, self.client_id = self.store.connect()
91
+ return self
92
+
93
+ async def __aenter__(self):
94
+ self.client_id: str = str(uuid.uuid4())
95
+ self.client, self.client_id = self.store.connect()
96
+ return self
97
+
98
+ async def __aexit__(self, exc_type, exc_value, traceback):
99
+ self.client.close() # closing database connection
100
+ # closing the connection:
101
+ self.store.close(client_id=self.client_id)
102
+
103
+ def __exit__(self, exc_type, exc_value, traceback):
104
+ self.client.close() # closing database connection
105
+ # closing the connection:
106
+ self.store.close(client_id=self.client_id)
107
+
108
+ def create_memory(
109
+ self,
110
+ key: str = 'chat_history',
111
+ input_key: str = 'question'
112
+ ):
113
+ return ConversationBufferMemory(
114
+ memory_key=key,
115
+ return_messages=True,
116
+ input_key=input_key
117
+ )
118
+
119
+ ### Different types of Retrieval
120
+ def conversation(
121
+ self,
122
+ question: str = None,
123
+ chain_type: str = 'stuff',
124
+ search_type: str = 'similarity',
125
+ search_kwargs: dict = {"k": 10, "fetch_k": 30, "lambda_mult": 0.86},
126
+ return_docs: bool = True,
127
+ metric_type: str = None,
128
+ memory: Any = None,
129
+ use_llm: str = None,
130
+ **kwargs
131
+ ):
132
+ # Question:
133
+ self._question = question
134
+ # Memory:
135
+ self.memory = memory
136
+ # Get a Vector Retriever:
137
+ vector = self.store.get_vector(
138
+ metric_type=metric_type
139
+ )
140
+ retriever = VectorStoreRetriever(
141
+ vectorstore=vector,
142
+ search_type=search_type,
143
+ chain_type=chain_type,
144
+ search_kwargs=search_kwargs
145
+ )
146
+ if self.kb:
147
+ # Get a BM25 Retriever:
148
+ b25_retriever = BM25Retriever.from_documents(self.kb)
149
+ retriever = EnsembleRetriever(
150
+ retrievers=[retriever, b25_retriever],
151
+ weights=[0.9, 0.1]
152
+ )
153
+ custom_template = self.template.format_map(
154
+ SafeDict(
155
+ summaries=''
156
+ )
157
+ )
158
+ _prompt = PromptTemplate(
159
+ template=custom_template,
160
+ input_variables=["context", "chat_history", "question"],
161
+ )
162
+ if use_llm is not None:
163
+ if use_llm == 'claude':
164
+ if ANTHROPIC_ENABLED is True:
165
+ llm = Anthropic(
166
+ model='claude-3-opus-20240229',
167
+ temperature=0.2,
168
+ top_p=0.4,
169
+ top_k=20
170
+ )
171
+ else:
172
+ raise ValueError(
173
+ "No Anthropic Claude was installed."
174
+ )
175
+ elif use_llm == 'vertex':
176
+ if VERTEX_ENABLED is True:
177
+ llm = VertexLLM(
178
+ model='gemini-pro',
179
+ temperature=0.2,
180
+ top_p=0.4,
181
+ top_k=20
182
+ )
183
+ else:
184
+ raise ValueError(
185
+ "No VertexAI was installed."
186
+ )
187
+ else:
188
+ raise ValueError(
189
+ f"Only Claude and Vertex are Supported Now."
190
+ )
191
+ _model = llm.get_llm()
192
+ else:
193
+ _model = self.model
194
+ # Conversational Chain:
195
+ self.chain = ConversationalRetrievalChain.from_llm(
196
+ llm=_model,
197
+ retriever=retriever,
198
+ chain_type=chain_type,
199
+ verbose=True,
200
+ memory=self.memory,
201
+ return_source_documents=return_docs,
202
+ return_generated_question=True,
203
+ combine_docs_chain_kwargs={"prompt": _prompt},
204
+ )
205
+ return self
206
+
207
+ def qa(
208
+ self,
209
+ question: str = None,
210
+ chain_type: str = 'stuff',
211
+ search_type: str = 'mmr',
212
+ search_kwargs: dict = {"k": 10, "fetch_k": 20, "lambda_mult": 0.86},
213
+ return_docs: bool = True,
214
+ metric_type: str = None,
215
+ use_llm: str = None
216
+ ):
217
+ # Question:
218
+ self._question = question
219
+ # Get a Vector Retriever:
220
+ vector = self.store.get_vector(
221
+ metric_type=metric_type
222
+ )
223
+ simil_retriever = VectorStoreRetriever(
224
+ vectorstore=vector,
225
+ search_type='similarity',
226
+ chain_type=chain_type,
227
+ search_kwargs=search_kwargs
228
+ )
229
+ retriever = vector.as_retriever(
230
+ search_type=search_type,
231
+ search_kwargs=search_kwargs
232
+ )
233
+ if self.kb:
234
+ # Get a BM25 Retriever:
235
+ b25_retriever = BM25Retriever.from_documents(self.kb)
236
+ retriever = EnsembleRetriever(
237
+ retrievers=[simil_retriever, retriever, b25_retriever],
238
+ weights=[0.3, 0.6, 0.1]
239
+ )
240
+ else:
241
+ # retriever = EnsembleRetriever(
242
+ # retrievers=[simil_retriever, retriever],
243
+ # weights=[0.7, 0.3]
244
+ # )
245
+ retriever = simil_retriever
246
+ custom_template = self.template.format_map(
247
+ SafeDict(
248
+ chat_history=''
249
+ )
250
+ )
251
+ if use_llm is not None:
252
+ if use_llm == 'claude':
253
+ if ANTHROPIC_ENABLED is True:
254
+ llm = Anthropic(
255
+ model='claude-3-opus-20240229',
256
+ temperature=0.2,
257
+ top_p=0.4,
258
+ top_k=20
259
+ )
260
+ else:
261
+ raise ValueError(
262
+ "No Anthropic Claude was installed."
263
+ )
264
+ elif use_llm == 'vertex':
265
+ if VERTEX_ENABLED is True:
266
+ llm = VertexLLM(
267
+ model='gemini-pro',
268
+ temperature=0.2,
269
+ top_p=0.4,
270
+ top_k=20
271
+ )
272
+ else:
273
+ raise ValueError(
274
+ "No VertexAI was installed."
275
+ )
276
+ else:
277
+ raise ValueError(
278
+ f"Only Claude and Vertex are Supported Now."
279
+ )
280
+ self.model = llm.get_llm()
281
+
282
+ self.chain = RetrievalQA.from_chain_type(
283
+ llm=self.model,
284
+ chain_type=chain_type,
285
+ retriever=retriever,
286
+ return_source_documents=return_docs,
287
+ chain_type_kwargs={
288
+ "prompt": PromptTemplate(
289
+ template=custom_template,
290
+ input_variables=['summaries', 'question']
291
+ )
292
+ },
293
+ )
294
+ # print('=====================')
295
+ # print(custom_template)
296
+ # response = self.chain.invoke(question)
297
+ # print('Q > ', response['result'])
298
+ # docs = vector.similarity_search(
299
+ # self._question, k=10
300
+ # )
301
+ # print(" LENGHT DOCS > ", len(docs))
302
+ # print(docs)
303
+ # print(' ========================== ')
304
+
305
+ # try:
306
+ # distance = self.evaluate_distance(
307
+ # self.store.embedding_name, question, docs
308
+ # )
309
+ # print('DISTANCE > ', distance)
310
+ # except Exception as e:
311
+ # distance = 'EMPTY'
312
+ # print('DISTANCE > ', distance)
313
+ # print('CHAIN > ', self.chain)
314
+ return self
315
+
316
+ def get_current_context(self):
317
+ if self.memory:
318
+ return self.memory.buffer_as_str()
319
+ return None
320
+
321
+ def as_markdown(self, response: ChatResponse) -> str:
322
+ markdown_output = f"**Question**: {response.question} \n"
323
+ markdown_output += f"**Answer**: {response.answer} \n"
324
+ if response.source_documents:
325
+ source_documents = response.source_documents
326
+ current_sources = []
327
+ block_sources = []
328
+ count = 0
329
+ d = {}
330
+ for source in source_documents:
331
+ if count >= 10:
332
+ break # Exit loop after processing 10 documents
333
+ metadata = source.metadata
334
+ if 'url' in metadata:
335
+ src = metadata.get('url')
336
+ elif 'filename' in metadata:
337
+ src = metadata.get('filename')
338
+ else:
339
+ src = metadata.get('source', 'unknown')
340
+ if src == 'knowledge-base':
341
+ continue # avoid attaching kb documents
342
+ source_title = metadata.get('title', src)
343
+ if source_title in current_sources:
344
+ continue
345
+ current_sources.append(source_title)
346
+ if src:
347
+ d[src] = metadata.get('document_meta', {})
348
+ source_filename = metadata.get('filename', src)
349
+ if src:
350
+ block_sources.append(f"- [{source_title}]({src})")
351
+ else:
352
+ if 'page_number' in metadata:
353
+ block_sources.append(f"- {source_filename} (Page {metadata.get('page_number')})")
354
+ else:
355
+ block_sources.append(f"- {source_filename}")
356
+ if block_sources:
357
+ markdown_output += f"**Sources**: \n"
358
+ markdown_output += "\n".join(block_sources)
359
+ if d:
360
+ response.documents = d
361
+ return markdown_output
362
+
363
+ def evaluate_distance(self, model, question, source_documents):
364
+ tokenizer = SentenceTransformer(model)
365
+ query_embedding = tokenizer.encode(question)
366
+ document_embeddings = [
367
+ tokenizer.encode(doc.page_content) for doc in source_documents
368
+ ]
369
+ distances = util.cos_sim(query_embedding, document_embeddings)
370
+ result = []
371
+ for doc, distance in zip(source_documents, distances):
372
+ result.append({
373
+ "document": doc,
374
+ "distance": distance
375
+ })
376
+ return result
377
+
378
+ async def log_usage(self, response: ChatResponse, request: web.Request = None):
379
+ PARAMS = {
380
+ "credentials": BIGQUERY_CREDENTIALS,
381
+ "project_id": BIGQUERY_PROJECT_ID,
382
+ }
383
+ db = AsyncDB(
384
+ 'bigquery',
385
+ params=PARAMS
386
+ )
387
+ origin = {
388
+ "user_agent": 'script'
389
+ }
390
+ user_id = 0
391
+ if request:
392
+ origin = {
393
+ "origin": request.remote,
394
+ "user_agent": request.headers.get('User-Agent')
395
+ }
396
+ session = await get_session(request)
397
+ if session:
398
+ user_id = session.user_id
399
+ async with await db.connection() as conn: #pylint: disable=E1101
400
+ # set connection to model:
401
+ ChatbotUsage.Meta.connection = conn
402
+ # Add a new record of chatbot usage:
403
+ record = {
404
+ "chatbot_id": str(self.chatbot_id),
405
+ "user_id": user_id, # TODO: add session informtion
406
+ "source_path": self.source_path,
407
+ "platform": 'web',
408
+ "sid": str(response.sid),
409
+ "used_at": response.at,
410
+ "question": response.question,
411
+ "response": response.answer,
412
+ **origin
413
+ }
414
+ try:
415
+ log = ChatbotUsage(**record)
416
+ data = log.to_dict()
417
+ # convert to string (bigquery uses json.dumps to convert to string)
418
+ data['sid'] = str(data['sid'])
419
+ data['chatbot_id'] = str(data['chatbot_id'])
420
+ data['event_timestamp'] = str(data['event_timestamp'])
421
+ # writing directly to bigquery
422
+ await conn.write(
423
+ [data],
424
+ table_id=ChatbotUsage.Meta.name,
425
+ dataset_id=ChatbotUsage.Meta.schema,
426
+ use_streams=False,
427
+ use_pandas=False
428
+ )
429
+ # await log.insert()
430
+ except Exception as exc:
431
+ self.logger.error(
432
+ f"Error inserting log: {exc}"
433
+ )
434
+
435
+
436
+ def question(self, question):
437
+ # vector = self.store.get_vector()
438
+ # docs = vector.similarity_search(self._question, k=1)
439
+ # max_confidence_score = 0
440
+ # for doc_id, similarity_score in docs:
441
+ # max_confidence_score = max(max_confidence_score, similarity_score)
442
+ try:
443
+ # Invoke the chain with the given question
444
+ response = self.chain.invoke(question)
445
+ except Exception as exc:
446
+ self.logger.error(
447
+ f"Error invoking chain: {exc}"
448
+ )
449
+ return None, None
450
+ try:
451
+ qa_response = ChatResponse(**response)
452
+ except (ValueError, TypeError) as exc:
453
+ self.logger.error(
454
+ f"Error validating response: {exc}"
455
+ )
456
+ return None, None
457
+ except ValidationError as exc:
458
+ self.logger.error(
459
+ f"Error on response: {exc.payload}"
460
+ )
461
+ return None, None
462
+ try:
463
+ return self.as_markdown(
464
+ qa_response
465
+ ), qa_response
466
+ except Exception as exc:
467
+ self.logger.exception(
468
+ f"Error on response: {exc}"
469
+ )
470
+ return None, None
471
+
472
+ async def invoke(self, question):
473
+ # Invoke the chain with the given question
474
+ try:
475
+ response = self.chain.invoke(
476
+ question
477
+ )
478
+ except Exception as exc:
479
+ self.logger.error(
480
+ f"Error invoking chain: {exc}"
481
+ )
482
+ return None, None
483
+ try:
484
+ print('RESPONSE > ', response)
485
+ qa_response = ChatResponse(**response)
486
+ except (ValueError, TypeError) as exc:
487
+ self.logger.error(
488
+ f"Error validating response: {exc}"
489
+ )
490
+ return None, None
491
+ except ValidationError as exc:
492
+ self.logger.error(
493
+ f"Error on response: {exc.payload}"
494
+ )
495
+ return None, None
496
+ try:
497
+ qa_response.response = self.as_markdown(
498
+ qa_response
499
+ )
500
+ # saving question to Usage Log
501
+ if self.request:
502
+ tasker = self.request.app['service_queue']
503
+ await tasker.put(
504
+ self.log_usage,
505
+ response=qa_response,
506
+ request=self.request
507
+ )
508
+ else:
509
+ asyncio.create_task(self.log_usage(response=qa_response))
510
+ return qa_response
511
+ except Exception as exc:
512
+ self.logger.exception(
513
+ f"Error on response: {exc}"
514
+ )
515
+ return None, None
@@ -0,0 +1,19 @@
1
+ from langchain.chains.constitutional_ai.base import ConstitutionalChain
2
+ from langchain.chains.constitutional_ai.models import ConstitutionalPrinciple
3
+ from ...conf import ETHICAL_PRINCIPLE
4
+
5
+
6
+ ethical_principle = ConstitutionalPrinciple(
7
+ name="Ethical Principle",
8
+ critique_request=ETHICAL_PRINCIPLE,
9
+ revision_request="Rewrite the model's output to be both ethical and legal.",
10
+ )
11
+
12
+
13
+ def get_constitutional_chain(llm, qa_chain):
14
+ return ConstitutionalChain.from_llm(
15
+ chain=qa_chain,
16
+ constitutional_principles=[ethical_principle],
17
+ llm=llm,
18
+ verbose=True,
19
+ )
parrot/conf.py ADDED
@@ -0,0 +1,108 @@
1
+ from pathlib import Path
2
+ from navconfig import config, BASE_DIR
3
+ from navconfig.logging import logging
4
+ from navigator.conf import default_dsn, CACHE_HOST, CACHE_PORT
5
+
6
+
7
+ # disable debug on some libraries:
8
+ logging.getLogger(name='httpcore').setLevel(logging.INFO)
9
+ logging.getLogger(name='httpx').setLevel(logging.INFO)
10
+ logging.getLogger(name='groq').setLevel(logging.INFO)
11
+ logging.getLogger(name='h5py').setLevel(logging.INFO)
12
+ logging.getLogger(name='tensorflow').setLevel(logging.INFO)
13
+
14
+
15
+ # Static directory
16
+ STATIC_DIR = config.get('STATIC_DIR', fallback=BASE_DIR.joinpath('static'))
17
+ if isinstance(STATIC_DIR, str):
18
+ STATIC_DIR = Path(STATIC_DIR)
19
+
20
+ # LLM Model
21
+ DEFAULT_LLM_MODEL_NAME = config.get('LLM_MODEL_NAME', fallback='gemini-pro')
22
+
23
+
24
+ ## MILVUS DB ##:
25
+ MILVUS_HOST = config.get('MILVUS_HOST', fallback='localhost')
26
+ MILVUS_PROTOCOL = config.get('MILVUS_PROTOCOL', fallback='http')
27
+ MILVUS_PORT = config.get('MILVUS_PORT', fallback=19530)
28
+ MILVUS_URL = config.get('MILVUS_URL')
29
+ MILVUS_TOKEN = config.get('MILVUS_TOKEN')
30
+ MILVUS_USER = config.get('MILVUS_USER')
31
+ MILVUS_PASSWORD = config.get('MILVUS_PASSWORD')
32
+ MILVUS_SECURE = config.getboolean('MILVUS_SECURE', fallback=False)
33
+ MILVUS_SERVER_NAME = config.get(
34
+ 'MILVUS_SERVER_NAME'
35
+ )
36
+ MILVUS_CA_CERT = config.get('MILVUS_CA_CERT', fallback=None)
37
+ MILVUS_SERVER_CERT = config.get('MILVUS_SERVER_CERT', fallback=None)
38
+ MILVUS_SERVER_KEY = config.get('MILVUS_SERVER_KEY', fallback=None)
39
+ MILVUS_USE_TLSv2 = config.getboolean('MILVUS_USE_TLSv2', fallback=False)
40
+
41
+ # ScyllaDB Database:
42
+ SCYLLADB_DRIVER = config.get('SCYLLADB_DRIVER', fallback='scylladb')
43
+ SCYLLADB_HOST = config.get('SCYLLADB_HOST', fallback='localhost')
44
+ SCYLLADB_PORT = int(config.get('SCYLLADB_PORT', fallback=9042))
45
+ SCYLLADB_USERNAME = config.get('SCYLLADB_USERNAME', fallback='navigator')
46
+ SCYLLADB_PASSWORD = config.get('SCYLLADB_PASSWORD', fallback='navigator')
47
+ SCYLLADB_KEYSPACE = config.get('SCYLLADB_KEYSPACE', fallback='navigator')
48
+
49
+
50
+ # BigQuery Configuration:
51
+ BIGQUERY_CREDENTIALS = config.get('BIGQUERY_CREDENTIALS')
52
+ BIGQUERY_PROJECT_ID = config.get('BIGQUERY_PROJECT_ID', fallback='navigator')
53
+ BIGQUERY_DATASET = config.get('BIGQUERY_DATASET', fallback='navigator')
54
+
55
+ # Redis History Configuration:
56
+ REDIS_HISTORY_DB = config.get('REDIS_HISTORY_DB', fallback=3)
57
+ REDIS_HISTORY_URL = f"redis://{CACHE_HOST}:{CACHE_PORT}/{REDIS_HISTORY_DB}"
58
+
59
+ def resolve_cert(crt):
60
+ cert = Path(crt)
61
+ if not cert.is_absolute():
62
+ cert = BASE_DIR.joinpath(cert)
63
+ else:
64
+ cert.resolve()
65
+ return cert
66
+
67
+ if MILVUS_SERVER_CERT:
68
+ MILVUS_SERVER_CERT = str(resolve_cert(MILVUS_SERVER_CERT))
69
+ if MILVUS_CA_CERT:
70
+ MILVUS_CA_CERT = str(resolve_cert(MILVUS_CA_CERT))
71
+ if MILVUS_SERVER_KEY:
72
+ MILVUS_SERVER_KEY = str(resolve_cert(MILVUS_SERVER_KEY))
73
+
74
+ # QDRANT:
75
+ QDRANT_PROTOCOL = config.get('QDRANT_PROTOCOL', fallback='http')
76
+ QDRANT_HOST = config.get('QDRANT_HOST', fallback='localhost')
77
+ QDRANT_PORT = config.get('QDRANT_PORT', fallback=6333)
78
+ QDRANT_USE_HTTPS = config.getboolean('QDRANT_USE_HTTPS', fallback=False)
79
+ QDRANT_URL = config.get('QDRANT_URL')
80
+ # QDRANT Connection Type: server or cloud
81
+ QDRANT_CONN_TYPE = config.get('QDRANT_CONN_TYPE', fallback='server')
82
+
83
+
84
+ # Embedding Device:
85
+ EMBEDDING_DEVICE = config.get('EMBEDDING_DEVICE', fallback='cpu')
86
+ EMBEDDING_DEFAULT_MODEL = config.get(
87
+ 'EMBEDDING_DEFAULT_MODEL',
88
+ fallback='sentence-transformers/sentence-t5-large'
89
+ )
90
+ MAX_VRAM_AVAILABLE = config.get('MAX_VRAM_AVAILABLE', fallback=20000)
91
+ RAM_AVAILABLE = config.get('RAM_AVAILABLE', fallback=819200)
92
+ CUDA_DEFAULT_DEVICE = config.get('CUDA_DEFAULT_DEVICE', fallback=0)
93
+ MAX_BATCH_SIZE = config.get('MAX_BATCH_SIZE', fallback=768)
94
+
95
+ # Enable Teams Bot:
96
+ ENABLE_AZURE_BOT = config.getboolean('ENABLE_AZURE_BOT', fallback=True)
97
+
98
+ ## Google API:
99
+ GOOGLE_API_KEY = config.get('GOOGLE_API_KEY')
100
+ ### Google Service Credentials:
101
+ GA_SERVICE_ACCOUNT_NAME = config.get('GA_SERVICE_ACCOUNT_NAME', fallback="google.json")
102
+ GA_SERVICE_PATH = config.get('GA_SERVICE_PATH', fallback="env/google/")
103
+
104
+ # Ethical Principle:
105
+ ETHICAL_PRINCIPLE = config.get(
106
+ 'ETHICAL_PRINCIPLE',
107
+ fallback='The model should only talk about ethical and legal things.'
108
+ )
@@ -0,0 +1,3 @@
1
+ """
2
+ NAV Crew is using CrewAI to manage the crew members and their roles.
3
+ """
@@ -0,0 +1,22 @@
1
+ """
2
+ A Directory for adding more Tools to CrewAI
3
+ """
4
+ from .duckgo import DuckDuckGoRelevantSearch, DuckDuckGoSearchTool
5
+ from .rag import RagSearchTool
6
+ from .file import SaveFile
7
+ from .bing import BingSearchTool
8
+ from .md2pdf import MarkdownToPDFTool
9
+ from .google import GoogleSearchTool, GoogleSiteSearchTool, GoogleLocationFinder
10
+
11
+
12
+ __all__ = [
13
+ 'GoogleSearchTool',
14
+ 'GoogleSiteSearchTool',
15
+ 'BingSearchTool',
16
+ 'DuckDuckGoRelevantSearch',
17
+ 'DuckDuckGoSearchTool',
18
+ 'RagSearchTool',
19
+ 'SaveFile',
20
+ 'MarkdownToPDFTool',
21
+ 'GoogleLocationFinder',
22
+ ]
@@ -0,0 +1,13 @@
1
+ from langchain_community.utilities.bing_search import BingSearchAPIWrapper
2
+ from crewai_tools import BaseTool
3
+
4
+
5
+ class BingSearchTool(BaseTool):
6
+ """Microsoft Bing Search Tool."""
7
+ name: str = "Microsoft Bing Search"
8
+ description: str = "Search the web using Microsoft Bing Search API"
9
+
10
+ def _run(self, query: str) -> dict:
11
+ """Run the Bing Search Tool."""
12
+ bing = BingSearchAPIWrapper(k=5)
13
+ return bing.results(query=query, num_results=5)