Update app.py
Browse files
app.py
CHANGED
@@ -323,58 +323,67 @@ headers = {"Authorization": f"Bearer {qwen}"}
|
|
323 |
|
324 |
def clean_output(output):
|
325 |
"""
|
326 |
-
Cleans the output from
|
327 |
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
328 |
lines = output.splitlines()
|
329 |
filtered_lines = []
|
330 |
-
|
331 |
-
|
332 |
for line in lines:
|
333 |
line = line.strip()
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
|
|
|
|
|
|
|
|
|
|
341 |
filtered_lines.append(line)
|
342 |
-
|
343 |
-
in_valid_section = False
|
344 |
-
|
345 |
return "\n".join(filtered_lines)
|
346 |
|
347 |
|
348 |
|
349 |
|
350 |
-
|
|
|
351 |
"""
|
352 |
-
Uses the Hugging Face Inference API to generate
|
|
|
353 |
"""
|
354 |
-
#
|
355 |
-
|
356 |
-
|
357 |
-
# Generate the refined prompt for Qwen
|
358 |
-
prompt = f"""
|
359 |
User-specified functionality: '{functionality_description}'
|
360 |
Functions identified by Gemini:
|
361 |
-
{
|
362 |
-
|
363 |
-
Tasks:
|
364 |
1. Generate a project summary:
|
365 |
'
|
366 |
Project Summary:
|
367 |
-
<
|
368 |
'
|
369 |
2. Refine the user-defined functionality:
|
370 |
'
|
371 |
Functionality Summary:
|
372 |
-
<
|
373 |
'
|
374 |
3. Describe the functionality flow:
|
375 |
'
|
376 |
Functionality Flow:
|
377 |
-
<
|
378 |
'
|
379 |
4. Generate detailed documentation for each function:
|
380 |
'
|
@@ -390,20 +399,45 @@ def validate_and_generate_documentation(api_url, headers, gemini_output, functio
|
|
390 |
- Assumptions: <Any assumptions the function makes>
|
391 |
- Example Usage: <Example demonstrating usage>
|
392 |
'
|
393 |
-
5. Return only the required information for the above tasks, and exclude everything else.
|
394 |
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
395 |
|
396 |
-
#
|
397 |
-
|
398 |
-
response = requests.post(api_url, headers=headers, json=payload)
|
399 |
|
400 |
-
# Handle API response
|
401 |
-
if response.status_code == 200:
|
402 |
-
api_response = response.json()
|
403 |
-
output = api_response.get("generated_text", "") if isinstance(api_response, dict) else api_response[0].get("generated_text", "")
|
404 |
-
return clean_output(output)
|
405 |
-
else:
|
406 |
-
raise ValueError(f"Error during API call: {response.status_code}, {response.text}")
|
407 |
|
408 |
|
409 |
|
@@ -431,21 +465,30 @@ def generate_documentation_page():
|
|
431 |
# Call Gemini to identify required functions
|
432 |
gemini_result = identify_required_functions(project_folder, functionality)
|
433 |
|
434 |
-
#
|
|
|
|
|
|
|
|
|
435 |
final_documentation = validate_and_generate_documentation(
|
436 |
-
API_URL, headers, gemini_result, functionality
|
437 |
)
|
438 |
|
439 |
-
# Display the final documentation
|
440 |
st.success("Documentation generated successfully!")
|
441 |
st.text_area("Generated Documentation", final_documentation, height=600)
|
442 |
-
|
443 |
except Exception as e:
|
444 |
st.error(f"An error occurred: {e}")
|
445 |
else:
|
446 |
st.error("Project folder not found. Ensure the GitHub repository was cloned successfully.")
|
447 |
else:
|
448 |
st.error("Please enter the functionality to analyze.")
|
|
|
|
|
|
|
|
|
|
|
|
|
449 |
|
450 |
|
451 |
|
|
|
323 |
|
324 |
def clean_output(output):
|
325 |
"""
|
326 |
+
Cleans the output from the Hugging Face model to ensure only the relevant details are included.
|
327 |
"""
|
328 |
+
# Remove known markers for prompts and redundant sections
|
329 |
+
markers_to_exclude = [
|
330 |
+
"Functions identified by Gemini",
|
331 |
+
"Tasks:",
|
332 |
+
"Return only the required information",
|
333 |
+
"User-specified functionality:"
|
334 |
+
]
|
335 |
+
|
336 |
lines = output.splitlines()
|
337 |
filtered_lines = []
|
338 |
+
seen_sections = set()
|
339 |
+
|
340 |
for line in lines:
|
341 |
line = line.strip()
|
342 |
+
# Skip lines that are part of excluded markers
|
343 |
+
if any(marker in line for marker in markers_to_exclude):
|
344 |
+
continue
|
345 |
+
|
346 |
+
# Skip duplicate sections
|
347 |
+
if line.startswith("Project Summary:") or line.startswith("Functionality Summary:"):
|
348 |
+
if line in seen_sections:
|
349 |
+
continue
|
350 |
+
seen_sections.add(line)
|
351 |
+
|
352 |
+
# Skip empty lines
|
353 |
+
if line:
|
354 |
filtered_lines.append(line)
|
355 |
+
|
|
|
|
|
356 |
return "\n".join(filtered_lines)
|
357 |
|
358 |
|
359 |
|
360 |
|
361 |
+
|
362 |
+
def validate_and_generate_documentation(api_url, headers, gemini_output, file_contents, functionality_description):
|
363 |
"""
|
364 |
+
Uses the Hugging Face Inference API to generate documentation in chunks to avoid token limits
|
365 |
+
and ensures only clean output is returned.
|
366 |
"""
|
367 |
+
# Generate the refined prompt for the Qwen model
|
368 |
+
base_prompt = f"""
|
|
|
|
|
|
|
369 |
User-specified functionality: '{functionality_description}'
|
370 |
Functions identified by Gemini:
|
371 |
+
{gemini_output}
|
372 |
+
Qwen, identify the functions provided above in the project, and with the User-specified functionality in mind, perform these tasks:
|
|
|
373 |
1. Generate a project summary:
|
374 |
'
|
375 |
Project Summary:
|
376 |
+
<Qwen, include project description and library or module dependencies>
|
377 |
'
|
378 |
2. Refine the user-defined functionality:
|
379 |
'
|
380 |
Functionality Summary:
|
381 |
+
<Qwen, provide an enhanced description of user-specified functionality>
|
382 |
'
|
383 |
3. Describe the functionality flow:
|
384 |
'
|
385 |
Functionality Flow:
|
386 |
+
<Qwen, explain the sequence of functions and data flow>
|
387 |
'
|
388 |
4. Generate detailed documentation for each function:
|
389 |
'
|
|
|
399 |
- Assumptions: <Any assumptions the function makes>
|
400 |
- Example Usage: <Example demonstrating usage>
|
401 |
'
|
|
|
402 |
"""
|
403 |
+
|
404 |
+
# Split file contents into chunks to avoid exceeding token limits
|
405 |
+
max_chunk_size = 12000 # Adjust for tokenization overhead
|
406 |
+
file_chunks = []
|
407 |
+
current_chunk = base_prompt
|
408 |
+
|
409 |
+
for file_path, content in file_contents.items():
|
410 |
+
chunk_content = f"File: {os.path.basename(file_path)}\n{content}\n\n"
|
411 |
+
if len(current_chunk) + len(chunk_content) > max_chunk_size:
|
412 |
+
file_chunks.append(current_chunk)
|
413 |
+
current_chunk = base_prompt + chunk_content
|
414 |
+
else:
|
415 |
+
current_chunk += chunk_content
|
416 |
+
|
417 |
+
if current_chunk not in file_chunks:
|
418 |
+
file_chunks.append(current_chunk)
|
419 |
+
|
420 |
+
# Process each chunk through the API
|
421 |
+
full_output = ""
|
422 |
+
for chunk in file_chunks:
|
423 |
+
payload = {"inputs": chunk, "parameters": {"max_new_tokens": 2048}}
|
424 |
+
response = requests.post(api_url, headers=headers, json=payload)
|
425 |
+
|
426 |
+
if response.status_code == 200:
|
427 |
+
api_response = response.json()
|
428 |
+
if isinstance(api_response, list):
|
429 |
+
output = api_response[0].get("generated_text", "")
|
430 |
+
elif isinstance(api_response, dict):
|
431 |
+
output = api_response.get("generated_text", "")
|
432 |
+
else:
|
433 |
+
raise ValueError("Unexpected response format from Hugging Face API.")
|
434 |
+
full_output += output
|
435 |
+
else:
|
436 |
+
raise ValueError(f"Error during API call: {response.status_code}, {response.text}")
|
437 |
|
438 |
+
# Apply cleaning to remove unnecessary content
|
439 |
+
return clean_output(full_output)
|
|
|
440 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
441 |
|
442 |
|
443 |
|
|
|
465 |
# Call Gemini to identify required functions
|
466 |
gemini_result = identify_required_functions(project_folder, functionality)
|
467 |
|
468 |
+
# Read project files
|
469 |
+
file_paths = read_project_files(project_folder)
|
470 |
+
file_contents = read_files(file_paths)
|
471 |
+
|
472 |
+
# Call the Hugging Face API to generate documentation
|
473 |
final_documentation = validate_and_generate_documentation(
|
474 |
+
API_URL, headers, gemini_result, file_contents, functionality
|
475 |
)
|
476 |
|
477 |
+
# Display the cleaned final documentation
|
478 |
st.success("Documentation generated successfully!")
|
479 |
st.text_area("Generated Documentation", final_documentation, height=600)
|
|
|
480 |
except Exception as e:
|
481 |
st.error(f"An error occurred: {e}")
|
482 |
else:
|
483 |
st.error("Project folder not found. Ensure the GitHub repository was cloned successfully.")
|
484 |
else:
|
485 |
st.error("Please enter the functionality to analyze.")
|
486 |
+
|
487 |
+
# Button to navigate back to the project page
|
488 |
+
if st.button("Back to Project"):
|
489 |
+
st.session_state.page = "project_view"
|
490 |
+
st.rerun()
|
491 |
+
|
492 |
|
493 |
|
494 |
|