@@ -77,13 +77,77 @@ def _load_system_prompt(self, prompt_path: Path) -> str:
77
77
return (
78
78
"You are an AI research assistant. Your task is to research the user's query, "
79
79
"provide a concise summary, and list the sources used."
80
- )
80
+ )
81
81
82
82
def research_topic (self , query : str , model : str = DEFAULT_MODEL ) -> Dict [str , Any ]:
83
- """Placeholder for research function."""
84
- print (f"Researching (placeholder): '{ query } ' using model '{ model } '..." )
85
- # TODO: Implement actual API call here
86
- return {"summary" : "Placeholder summary" , "sources" : ["placeholder source" ], "raw_response" : "" }
83
+ """
84
+ Research a given topic or question using the Perplexity API.
85
+ """
86
+ if not query or not query .strip ():
87
+ return {"error" : "Input query is empty. Cannot perform research." }
88
+
89
+ headers = {
90
+ "accept" : "application/json" ,
91
+ "content-type" : "application/json" ,
92
+ "Authorization" : f"Bearer { self .api_key } "
93
+ }
94
+
95
+ data = {
96
+ "model" : model ,
97
+ "messages" : [
98
+ {"role" : "system" , "content" : self .system_prompt },
99
+ {"role" : "user" , "content" : query }
100
+ ]
101
+ # Consider adding other parameters like temperature, max_tokens if needed
102
+ }
103
+
104
+ try :
105
+ # Increased timeout for potentially longer research tasks
106
+ response = requests .post (self .API_URL , headers = headers , json = data , timeout = 90 )
107
+ response .raise_for_status () # Raise HTTPError for bad responses (4xx or 5xx)
108
+ result = response .json ()
109
+
110
+ if "choices" in result and result ["choices" ] and "message" in result ["choices" ][0 ]:
111
+ content = result ["choices" ][0 ]["message" ]["content" ]
112
+ # Basic parsing attempt (can be improved)
113
+ summary = content # Default to full content
114
+ sources_list = result .get ("citations" , []) # Use structured citations if available
115
+
116
+ # Simple text parsing if no structured citations and "Sources:" marker exists
117
+ if not sources_list and "Sources:" in content :
118
+ try :
119
+ parts = content .split ("Sources:" , 1 )
120
+ summary = parts [0 ].strip ()
121
+ sources_text = parts [1 ].strip ()
122
+ sources_list = [s .strip ().lstrip ('- ' ) for s in sources_text .split ('\n ' ) if s .strip ()]
123
+ except Exception :
124
+ summary = content # Revert if parsing fails
125
+ sources_list = []
126
+
127
+ return {
128
+ "summary" : summary ,
129
+ "sources" : sources_list ,
130
+ "raw_response" : content
131
+ }
132
+ else :
133
+ error_msg = "Unexpected API response format."
134
+ if "error" in result :
135
+ error_msg += f" API Error: { result ['error' ].get ('message' , 'Unknown error' )} "
136
+ return {"error" : error_msg , "raw_response" : result }
137
+
138
+ except RequestException as e :
139
+ error_message = f"API request failed: { str (e )} "
140
+ if e .response is not None :
141
+ try :
142
+ error_details = e .response .json ()
143
+ error_message += f" - { error_details .get ('error' , {}).get ('message' , e .response .text )} "
144
+ except json .JSONDecodeError :
145
+ error_message += f" - Status Code: { e .response .status_code } "
146
+ return {"error" : error_message }
147
+ except json .JSONDecodeError :
148
+ return {"error" : "Failed to parse API response as JSON" , "raw_response" : response .text if 'response' in locals () else 'No response object' }
149
+ except Exception as e :
150
+ return {"error" : f"An unexpected error occurred: { str (e )} " }
87
151
88
152
89
153
def display_results (results : Dict [str , Any ]):
0 commit comments