Skip to content

Commit bec6a16

Browse files
committed
Refactor session state management and repository loading in GitHub RAG application: Introduced dedicated functions for initializing session state and handling repository loading with improved error handling. Enhanced chat message processing and updated logging for better traceability.
1 parent 86aae73 commit bec6a16

File tree

1 file changed

+128
-114
lines changed

1 file changed

+128
-114
lines changed

github-rag/app.py

Lines changed: 128 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -167,128 +167,142 @@ def create_query_engine(content_path: str, repo_name: str) -> Any:
167167
logger.error(f"Error creating query engine: {str(e)}")
168168
raise QueryEngineError(f"Failed to create query engine: {str(e)}")
169169

170-
# Initialize session state
171-
if "id" not in st.session_state:
172-
st.session_state.id = uuid.uuid4()
173-
st.session_state.file_cache = {}
174-
st.session_state.messages = []
175-
176-
session_id = st.session_state.id
177-
178-
# Sidebar
179-
with st.sidebar:
180-
st.header("Add your GitHub repository!")
181-
182-
github_url = st.text_input(
183-
"Enter GitHub repository URL",
184-
placeholder="https://github.com/username/repo",
185-
help="Enter a valid GitHub repository URL"
186-
)
187-
188-
load_repo = st.button("Load Repository", type="primary")
189-
190-
if github_url and load_repo:
191-
try:
192-
# Validate URL
193-
if not validate_github_url(github_url):
194-
st.error("Please enter a valid GitHub repository URL")
195-
st.stop()
170+
def initialize_session_state():
171+
"""Initialize or reset session state variables"""
172+
try:
173+
if 'messages' not in st.session_state:
174+
st.session_state.messages = []
175+
if 'context' not in st.session_state:
176+
st.session_state.context = None
177+
if 'file_cache' not in st.session_state:
178+
st.session_state.file_cache = {}
179+
if 'current_repo' not in st.session_state:
180+
st.session_state.current_repo = None
181+
if 'query_engine' not in st.session_state:
182+
st.session_state.query_engine = None
183+
logger.info("Session state initialized successfully")
184+
except Exception as e:
185+
logger.error(f"Error initializing session state: {str(e)}")
186+
raise SessionError("Failed to initialize session state")
196187

197-
repo_name = get_repo_name(github_url)
198-
file_key = f"{session_id}-{repo_name}"
188+
def handle_repository_loading(github_url: str) -> None:
189+
"""Handle repository loading process with proper error handling"""
190+
try:
191+
validate_github_url(github_url)
192+
repo_name = get_repo_name(github_url)
193+
194+
with st.spinner(f"Processing repository {repo_name}..."):
195+
summary, tree, content = process_with_gitingets(github_url)
199196

200-
if file_key not in st.session_state.file_cache:
201-
with st.spinner("Processing your repository..."):
202-
with tempfile.TemporaryDirectory() as temp_dir:
203-
try:
204-
summary, tree, content = process_with_gitingets(github_url)
205-
206-
# Write content to temporary file
207-
content_path = os.path.join(temp_dir, f"{repo_name}_content.md")
208-
with open(content_path, "w", encoding="utf-8") as f:
209-
f.write(content)
210-
211-
# Create and cache query engine
212-
query_engine = create_query_engine(temp_dir, repo_name)
213-
st.session_state.file_cache[file_key] = query_engine
214-
215-
st.success("Repository loaded successfully! Ready to chat.")
216-
logger.info(f"Successfully processed repository: {repo_name}")
217-
218-
except ProcessingError as e:
219-
st.error(str(e))
220-
logger.error(f"Error processing repository {repo_name}: {str(e)}")
221-
st.stop()
222-
except Exception as e:
223-
st.error("An unexpected error occurred while processing the repository")
224-
logger.error(f"Unexpected error: {str(e)}")
225-
st.stop()
226-
else:
227-
st.info("Repository already loaded. Ready to chat!")
197+
# Create temporary directory for repository content
198+
with tempfile.TemporaryDirectory() as temp_dir:
199+
content_path = os.path.join(temp_dir, repo_name)
200+
os.makedirs(content_path, exist_ok=True)
228201

229-
except Exception as e:
230-
st.error(f"An error occurred: {str(e)}")
231-
logger.error(f"Error in repository loading process: {str(e)}")
232-
st.stop()
233-
234-
# Main content
235-
col1, col2 = st.columns([6, 1])
236-
237-
with col1:
238-
st.header("Chat with GitHub using RAG </>")
239-
240-
with col2:
241-
st.button("Clear Chat ↺", on_click=reset_chat, help="Clear chat history and reset session")
242-
243-
# Display chat history
244-
for message in st.session_state.messages:
245-
with st.chat_message(message["role"]):
246-
st.markdown(message["content"])
202+
# Save repository content
203+
for file_path, file_content in content.items():
204+
file_dir = os.path.dirname(os.path.join(content_path, file_path))
205+
os.makedirs(file_dir, exist_ok=True)
206+
with open(os.path.join(content_path, file_path), 'w', encoding='utf-8') as f:
207+
f.write(file_content)
208+
209+
# Create query engine
210+
query_engine = create_query_engine(content_path, repo_name)
211+
212+
# Update session state
213+
st.session_state.query_engine = query_engine
214+
st.session_state.current_repo = repo_name
215+
st.session_state.context = {
216+
'summary': summary,
217+
'tree': tree,
218+
'content': content
219+
}
220+
221+
st.success(f"Successfully loaded repository: {repo_name}")
222+
logger.info(f"Repository {repo_name} loaded successfully")
223+
224+
except ValidationError as e:
225+
st.error(f"Validation error: {str(e)}")
226+
logger.warning(f"Validation error for URL {github_url}: {str(e)}")
227+
except ProcessingError as e:
228+
st.error(f"Processing error: {str(e)}")
229+
logger.error(f"Error processing repository {github_url}: {str(e)}")
230+
except QueryEngineError as e:
231+
st.error(f"Query engine error: {str(e)}")
232+
logger.error(f"Error creating query engine for {github_url}: {str(e)}")
233+
except Exception as e:
234+
st.error(f"Unexpected error: {str(e)}")
235+
logger.error(f"Unexpected error processing {github_url}: {str(e)}")
236+
finally:
237+
cleanup_session()
247238

248-
# Chat input
249-
if prompt := st.chat_input("What's up?"):
239+
def handle_chat_message(prompt: str) -> None:
240+
"""Handle chat message processing with proper error handling"""
250241
try:
251-
# Add user message to chat history
242+
if not st.session_state.query_engine:
243+
raise QueryEngineError("Please load a repository first!")
244+
245+
if not prompt.strip():
246+
raise ValidationError("Please enter a non-empty message")
247+
248+
# Add user message to chat
252249
st.session_state.messages.append({"role": "user", "content": prompt})
253250

254-
# Display user message
255-
with st.chat_message("user"):
256-
st.markdown(prompt)
251+
# Get response from query engine
252+
response = st.session_state.query_engine.query(prompt)
253+
254+
# Format and display response
255+
full_response = f"Repository: {st.session_state.current_repo}\n\n{response}"
256+
st.session_state.messages.append({"role": "assistant", "content": full_response})
257+
258+
logger.info(f"Successfully processed chat message for repository {st.session_state.current_repo}")
259+
260+
except ValidationError as e:
261+
st.error(f"Validation error: {str(e)}")
262+
logger.warning(f"Chat validation error: {str(e)}")
263+
except QueryEngineError as e:
264+
st.error(f"Query engine error: {str(e)}")
265+
logger.error(f"Error in chat processing: {str(e)}")
266+
except Exception as e:
267+
st.error(f"Unexpected error: {str(e)}")
268+
logger.error(f"Unexpected error in chat: {str(e)}")
257269

258-
# Process and display assistant response
259-
with st.chat_message("assistant"):
260-
message_placeholder = st.empty()
261-
full_response = ""
270+
def main():
271+
"""Main application function"""
272+
st.title("GitHub Repository RAG")
273+
274+
try:
275+
# Initialize session state
276+
initialize_session_state()
277+
278+
# Sidebar for repository input
279+
with st.sidebar:
280+
st.header("Repository Settings")
281+
github_url = st.text_input("Enter GitHub Repository URL")
262282

263-
try:
264-
repo_name = get_repo_name(github_url)
265-
file_key = f"{session_id}-{repo_name}"
266-
query_engine = st.session_state.file_cache.get(file_key)
267-
268-
if query_engine is None:
269-
raise QueryEngineError("Please load a repository first!")
270-
271-
response = query_engine.query(prompt)
272-
273-
if hasattr(response, 'response_gen'):
274-
for chunk in response.response_gen:
275-
if isinstance(chunk, str):
276-
full_response += chunk
277-
message_placeholder.markdown(full_response + "▌")
283+
if st.button("Load Repository"):
284+
if github_url:
285+
handle_repository_loading(github_url)
278286
else:
279-
full_response = str(response)
280-
message_placeholder.markdown(full_response)
281-
282-
message_placeholder.markdown(full_response)
283-
st.session_state.messages.append({"role": "assistant", "content": full_response})
284-
285-
except QueryEngineError as e:
286-
st.error(str(e))
287-
logger.error(f"Error in chat processing: {str(e)}")
288-
except Exception as e:
289-
st.error("An unexpected error occurred while processing your query")
290-
logger.error(f"Unexpected error in chat: {str(e)}")
291-
287+
st.warning("Please enter a GitHub repository URL")
288+
289+
if st.button("Reset Chat"):
290+
reset_chat()
291+
292+
# Main chat interface
293+
for message in st.session_state.messages:
294+
with st.chat_message(message["role"]):
295+
st.write(message["content"])
296+
297+
if prompt := st.chat_input("Ask a question about the repository"):
298+
handle_chat_message(prompt)
299+
300+
except SessionError as e:
301+
st.error(f"Session error: {str(e)}")
302+
logger.error(f"Session error in main: {str(e)}")
292303
except Exception as e:
293-
st.error("An error occurred in the chat system")
294-
logger.error(f"Chat system error: {str(e)}")
304+
st.error(f"Unexpected error: {str(e)}")
305+
logger.error(f"Unexpected error in main: {str(e)}")
306+
307+
if __name__ == "__main__":
308+
main()

0 commit comments

Comments
 (0)