Skip to content

Commit ba31811

Browse files
author
Kun Han
committed
WebUI: show final results and search results
1 parent 3ed837f commit ba31811

File tree

9 files changed

+1086
-80
lines changed

9 files changed

+1086
-80
lines changed

examples/tech_radar/agents/document_agent.py

+70-43
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,17 @@ async def read_document(
153153
response = client.docs.v1.content.get(request)
154154

155155
if not response.success():
156-
print(f"Failed to read document: {response.msg}")
156+
error_msg = response.msg
157+
print(f"Failed to read document: {error_msg}")
158+
159+
# Provide more specific error messages for common error codes
160+
if "not found" in error_msg.lower() or "not exist" in error_msg.lower():
161+
raise ValueError(f"Document not found. Please check if the document token is valid: {doc_token}")
162+
elif "permission" in error_msg.lower() or "access" in error_msg.lower():
163+
raise ValueError(f"Permission denied. You don't have access to this document: {doc_token}")
164+
else:
165+
raise ValueError(f"Error accessing document: {error_msg}")
166+
157167
return None
158168

159169
# Clean and format the content
@@ -162,7 +172,8 @@ async def read_document(
162172

163173
except Exception as e:
164174
print(f"Error reading document: {str(e)}")
165-
return None
175+
# Re-raise the error to be handled by the calling function
176+
raise
166177

167178
async def summarize_document(
168179
doc_token: str,
@@ -177,48 +188,64 @@ async def summarize_document(
177188
agent_config = get_agent_config("document")
178189
language = agent_config.get("language", "en")
179190

180-
# Read the document
181-
content = await read_document(doc_token)
182-
if not content:
183-
return None
184-
185-
# Create and run the summarization agent
186-
agent = create_document_agent(model, language)
187-
188191
try:
189-
result = await Runner.run(
190-
agent,
191-
content,
192-
run_config=RunConfig(
193-
model_provider=provider,
194-
model=model,
195-
model_settings=model_settings
196-
)
197-
)
192+
# Read the document
193+
content = await read_document(doc_token)
194+
if not content:
195+
raise ValueError(f"Failed to read document with token: {doc_token}")
196+
197+
# Create and run the summarization agent
198+
agent = create_document_agent(model, language)
198199

199-
# Validate the output
200-
summary = result.final_output_as(DocumentSummary)
201-
if not summary.questions:
202-
print("Warning: No questions were generated. Using fallback questions.")
203-
# Generate some basic fallback questions based on the content
204-
title = summary.content
205-
fallback_questions = [
206-
f"What are the key challenges in implementing {title}?",
207-
f"How might recent technological advances impact the future of {title}?",
208-
f"What are the potential limitations or drawbacks of current approaches to {title}?",
209-
f"How could we improve the efficiency and effectiveness of {title}?",
210-
f"What are the ethical considerations surrounding the deployment of {title}?"
211-
]
212-
summary.questions = fallback_questions
200+
try:
201+
result = await Runner.run(
202+
agent,
203+
content,
204+
run_config=RunConfig(
205+
model_provider=provider,
206+
model=model,
207+
model_settings=model_settings
208+
)
209+
)
210+
211+
# Validate the output
212+
summary = result.final_output_as(DocumentSummary)
213+
if not summary.questions:
214+
print("Warning: No questions were generated. Using fallback questions.")
215+
# Generate some basic fallback questions based on the content
216+
title = summary.content
217+
fallback_questions = [
218+
f"What are the key challenges in implementing {title}?",
219+
f"How might recent technological advances impact the future of {title}?",
220+
f"What are the potential limitations or drawbacks of current approaches to {title}?",
221+
f"How could we improve the efficiency and effectiveness of {title}?",
222+
f"What are the ethical considerations surrounding the deployment of {title}?"
223+
]
224+
summary.questions = fallback_questions
225+
226+
return summary
227+
228+
except Exception as e:
229+
print(f"Error during document summarization: {str(e)}")
230+
# Only create a fallback summary if we have content
231+
# Otherwise re-raise the original document access error
232+
if content:
233+
title = content.split('\\n')[0] if '\\n' in content else content[:50]
234+
return DocumentSummary(
235+
content=title,
236+
summary=f"Error generating summary: {str(e)[:100]}... Please try again with a different document or model.",
237+
questions=[]
238+
)
239+
else:
240+
raise
241+
242+
except ValueError as e:
243+
# Re-raise specific ValueError errors (like document not found)
244+
print(f"Document access error: {str(e)}")
245+
raise
213246

214-
return summary
215247
except Exception as e:
216-
print(f"Error during document summarization: {str(e)}")
217-
218-
# Create a simple fallback summary if JSON parsing fails
219-
title = content.split('\\n')[0] if '\\n' in content else content[:50]
220-
return DocumentSummary(
221-
content=title,
222-
summary=f"Error generating summary: {str(e)[:100]}... Please try again with a different document or model.",
223-
questions=[]
224-
)
248+
# Convert other exceptions to ValueError with a clear message
249+
error_msg = f"Error processing document: {str(e)}"
250+
print(error_msg)
251+
raise ValueError(error_msg)

examples/tech_radar/agents/search_agent.py

+46-5
Original file line numberDiff line numberDiff line change
@@ -114,11 +114,52 @@ async def search(self, query: str, reason: str = "") -> Dict[str, Any]:
114114
"sources": result.get("sources", [])
115115
}
116116
except json.JSONDecodeError:
117-
# If not JSON, treat the entire response as summary
118-
return {
119-
"summary": response,
120-
"sources": []
121-
}
117+
# If not JSON, check if it looks like a JSON object but has formatting issues
118+
if '{' in response and '}' in response and 'summary' in response:
119+
import re
120+
121+
# Try to extract summary and sources using regex
122+
logger.info("Attempting to extract JSON-like data from response")
123+
124+
# Extract summary
125+
summary = "No summary available"
126+
# Try different patterns to extract summary
127+
# First try to extract between quotes
128+
summary_match = re.search(r'["\']?summary["\']?\s*:\s*["\']([^"\'].*?)["\'](?=\s*,\s*["\']?sources["\']?)', response, re.DOTALL)
129+
if summary_match:
130+
summary = summary_match.group(1).strip()
131+
else:
132+
# Try to find content between "summary"/"sources" without relying on quotes
133+
summary_start = re.search(r'["\']?summary["\']?\s*:\s*', response)
134+
sources_start = re.search(r'["\']?sources["\']?\s*:', response)
135+
136+
if summary_start and sources_start and summary_start.end() < sources_start.start():
137+
# Get everything between end of "summary:" and start of "sources:"
138+
raw_summary = response[summary_start.end():sources_start.start()].strip()
139+
# Remove trailing comma and any quotes
140+
summary = re.sub(r',\s*$', '', raw_summary).strip(' \'"')
141+
142+
logger.info(f"Extracted summary (length: {len(summary)}): {summary[:50]}...")
143+
144+
# Extract sources
145+
sources = []
146+
sources_match = re.search(r'["\']?sources["\']?\s*:\s*\[(.*?)\]', response, re.DOTALL)
147+
if sources_match:
148+
sources_str = sources_match.group(1)
149+
# Split by commas and clean up
150+
sources = [s.strip().strip("'\"") for s in sources_str.split(',') if s.strip()]
151+
152+
logger.info(f"Extracted summary: {summary[:50]}... and {len(sources)} sources")
153+
return {
154+
"summary": summary,
155+
"sources": sources
156+
}
157+
else:
158+
# If not JSON-like, treat the entire response as summary
159+
return {
160+
"summary": response,
161+
"sources": []
162+
}
122163
except Exception as e:
123164
logger.error(f"Error processing response: {str(e)}")
124165
return {

examples/tech_radar/document_research_manager.py

+34-20
Original file line numberDiff line numberDiff line change
@@ -89,28 +89,42 @@ async def _analyze_document(self, doc_token: str) -> Optional[DocumentSummary]:
8989
"""Analyze the document and generate summary and questions."""
9090
self.printer.update_item("document_analysis", "Analyzing document...")
9191

92-
# Get agent configuration
93-
config = get_agent_config("document")
94-
provider_name = get_provider_for_agent("document")
95-
provider = PROVIDER_MAP[provider_name] # Get the actual provider object from the map
96-
97-
# Analyze the document
98-
analysis = await summarize_document(
99-
doc_token=doc_token,
100-
model=config["model"],
101-
provider=provider # Pass the provider object instead of the name
102-
)
92+
try:
93+
# Get agent configuration
94+
config = get_agent_config("document")
95+
provider_name = get_provider_for_agent("document")
96+
provider = PROVIDER_MAP[provider_name] # Get the actual provider object from the map
97+
98+
# Analyze the document
99+
analysis = await summarize_document(
100+
doc_token=doc_token,
101+
model=config["model"],
102+
provider=provider # Pass the provider object instead of the name
103+
)
104+
105+
if not analysis:
106+
self.printer.update_item("document_analysis", "Failed to analyze document", is_done=True)
107+
return None
108+
109+
self.printer.update_item(
110+
"document_analysis",
111+
f"Generated {len(analysis.questions)} key questions",
112+
is_done=True,
113+
)
114+
return analysis
103115

104-
if not analysis:
105-
self.printer.update_item("document_analysis", "Failed to analyze document", is_done=True)
106-
return None
116+
except ValueError as e:
117+
# Handle specific errors raised by read_document
118+
self.printer.update_item("document_analysis", f"Error: {str(e)}", is_done=True)
119+
logger.error(f"Document analysis error: {str(e)}")
120+
raise # Re-raise the error to be handled by the caller
107121

108-
self.printer.update_item(
109-
"document_analysis",
110-
f"Generated {len(analysis.questions)} key questions",
111-
is_done=True,
112-
)
113-
return analysis
122+
except Exception as e:
123+
# Handle other unexpected errors
124+
error_msg = f"Unexpected error during document analysis: {str(e)}"
125+
self.printer.update_item("document_analysis", error_msg, is_done=True)
126+
logger.error(error_msg)
127+
raise
114128

115129
async def _plan_searches(self, document_analysis: DocumentSummary) -> SearchPlan:
116130
"""Plan searches based on document analysis."""

examples/tech_radar/requirements.txt

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
python-dotenv>=1.0.0
22
lark-oapi>=1.0.0
3-
rich>=13.0.0
3+
rich>=13.0.0
4+
requests>=2.28.0

0 commit comments

Comments
 (0)