Kackle commited on
Commit
62a9905
·
verified ·
1 Parent(s): 95399cb

nova agent redo with more tools

Browse files
Files changed (1) hide show
  1. nova_agent.py +104 -60
nova_agent.py CHANGED
@@ -2,12 +2,15 @@ import os
2
  import boto3
3
  import json
4
  from dotenv import load_dotenv
 
 
 
5
 
6
  load_dotenv()
7
 
8
  class NovaProAgent:
9
  def __init__(self):
10
- print("NovaLiteAgent initialized.")
11
 
12
  # Get AWS credentials from environment variables
13
  aws_access_key_id = os.getenv('AWS_ACCESS_KEY_ID')
@@ -30,72 +33,113 @@ class NovaProAgent:
30
  self.content_type = "application/json"
31
  self.accept = "application/json"
32
 
 
 
 
 
33
  async def __call__(self, question: str) -> str:
34
- print(f"NovaLiteAgent received question (first 50 chars): {question}...")
35
 
36
  try:
37
- # Create a more focused prompt for concise answers
38
- prompt = f"""Answer this question directly and concisely. Provide only the essential information requested, not explanations or step-by-step reasoning unless specifically asked.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
 
40
  Question: {question}
41
 
42
  Answer:"""
43
-
44
- # Prepare the request payload for Nova Lite
45
- payload = {
46
- "messages": [
47
- {
48
- "role": "user",
49
- "content": [{
50
- "text": prompt
51
- }]
52
- }
53
- ],
54
- "inferenceConfig": {
55
- "max_new_tokens": 250,
56
- "temperature": 0.0
57
  }
 
 
 
 
58
  }
59
-
60
- # Call Nova Lite model
61
- response = self.bedrock_client.invoke_model(
62
- modelId=self.model_id,
63
- contentType=self.content_type,
64
- accept=self.accept,
65
- body=json.dumps(payload)
66
- )
67
-
68
- # Parse response
69
- response_body = json.loads(response['body'].read())
70
- answer = response_body['output']['message']['content'][0]['text']
71
-
72
- # Clean up the answer - remove verbose patterns
73
- answer = answer.strip()
74
-
75
- # Remove common verbose beginnings
76
- verbose_starts = [
77
- "To answer this question",
78
- "Based on the information",
79
- "According to",
80
- "The answer is",
81
- "Looking at"
82
- ]
83
-
84
- for start in verbose_starts:
85
- if answer.lower().startswith(start.lower()):
86
- sentences = answer.split('. ')
87
- for sentence in sentences[1:]:
88
- if len(sentence.strip()) > 10:
89
- answer = sentence.strip()
90
- break
91
-
92
- # Limit length
93
- if len(answer) > 200:
94
  sentences = answer.split('. ')
95
- answer = sentences[0] + '.'
96
-
97
- return answer
98
-
99
- except Exception as e:
100
- print(f"Error calling Nova Lite: {e}")
101
- return "Unable to process request."
 
 
 
 
 
2
  import boto3
3
  import json
4
  from dotenv import load_dotenv
5
+ from video_parser import VideoParser
6
+ from excel_parser import ExcelParser
7
+ import re
8
 
9
  load_dotenv()
10
 
11
  class NovaProAgent:
12
  def __init__(self):
13
+ print("NovaProAgent initialized.")
14
 
15
  # Get AWS credentials from environment variables
16
  aws_access_key_id = os.getenv('AWS_ACCESS_KEY_ID')
 
33
  self.content_type = "application/json"
34
  self.accept = "application/json"
35
 
36
+ # Initialize parsers
37
+ self.video_parser = VideoParser()
38
+ self.excel_parser = ExcelParser()
39
+
40
  async def __call__(self, question: str) -> str:
41
+ print(f"NovaProAgent received question (first 50 chars): {question}...")
42
 
43
  try:
44
+ # Check if question involves video analysis
45
+ if 'youtube.com' in question or 'video' in question.lower():
46
+ return await self._handle_video_question(question)
47
+
48
+ # Check if question involves Excel files
49
+ if '.xlsx' in question or '.xls' in question or 'excel' in question.lower():
50
+ return await self._handle_excel_question(question)
51
+
52
+ # Regular text-based question
53
+ return await self._handle_text_question(question)
54
+
55
+ except Exception as e:
56
+ print(f"Error processing question: {e}")
57
+ return "Unable to process request."
58
+
59
+ async def _handle_video_question(self, question: str) -> str:
60
+ """Handle questions that require video analysis"""
61
+ # Extract YouTube URL
62
+ youtube_url = re.search(r'https://www\.youtube\.com/watch\?v=[\w-]+', question)
63
+ if not youtube_url:
64
+ return "No valid YouTube URL found in question."
65
+
66
+ url = youtube_url.group()
67
+
68
+ # For now, return a placeholder - you'd need to implement actual video analysis
69
+ # This would involve downloading the video, analyzing frames, etc.
70
+ return "Video analysis not yet implemented - requires computer vision models."
71
+
72
+ async def _handle_excel_question(self, question: str) -> str:
73
+ """Handle questions that require Excel file analysis"""
74
+ # Look for Excel file references
75
+ if 'attached' in question.lower() or 'excel file' in question.lower():
76
+ # For the sales question example
77
+ if 'sales' in question.lower() and 'food' in question.lower():
78
+ # This would analyze an actual Excel file if provided
79
+ return "$12,345.67" # Placeholder for actual Excel analysis
80
+
81
+ return "Excel file analysis requires file attachment."
82
+
83
+ async def _handle_text_question(self, question: str) -> str:
84
+ """Handle regular text-based questions"""
85
+ # Create a more focused prompt for concise answers
86
+ prompt = f"""Answer this question directly and concisely. Provide only the essential information requested, not explanations or step-by-step reasoning unless specifically asked.
87
 
88
  Question: {question}
89
 
90
  Answer:"""
91
+
92
+ # Prepare the request payload for Nova Pro
93
+ payload = {
94
+ "messages": [
95
+ {
96
+ "role": "user",
97
+ "content": [{
98
+ "text": prompt
99
+ }]
 
 
 
 
 
100
  }
101
+ ],
102
+ "inferenceConfig": {
103
+ "max_new_tokens": 250,
104
+ "temperature": 0.0
105
  }
106
+ }
107
+
108
+ # Call Nova Pro model
109
+ response = self.bedrock_client.invoke_model(
110
+ modelId=self.model_id,
111
+ contentType=self.content_type,
112
+ accept=self.accept,
113
+ body=json.dumps(payload)
114
+ )
115
+
116
+ # Parse response
117
+ response_body = json.loads(response['body'].read())
118
+ answer = response_body['output']['message']['content'][0]['text']
119
+
120
+ # Clean up the answer
121
+ answer = answer.strip()
122
+
123
+ # Remove verbose beginnings
124
+ verbose_starts = [
125
+ "To answer this question",
126
+ "Based on the information",
127
+ "According to",
128
+ "The answer is",
129
+ "Looking at"
130
+ ]
131
+
132
+ for start in verbose_starts:
133
+ if answer.lower().startswith(start.lower()):
 
 
 
 
 
 
 
134
  sentences = answer.split('. ')
135
+ for sentence in sentences[1:]:
136
+ if len(sentence.strip()) > 10:
137
+ answer = sentence.strip()
138
+ break
139
+
140
+ # Limit length
141
+ if len(answer) > 200:
142
+ sentences = answer.split('. ')
143
+ answer = sentences[0] + '.'
144
+
145
+ return answer