Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -5,8 +5,12 @@ import time # For progress updates
|
|
5 |
|
6 |
# --- Core Logic Imports ---
|
7 |
# Initialize clients first to ensure API keys are loaded before other modules use them.
|
8 |
-
from core.llm_clients import initialize_all_clients,
|
9 |
-
initialize_all_clients() # Call initialization
|
|
|
|
|
|
|
|
|
10 |
|
11 |
from core.generation_engine import generate_initial_solutions
|
12 |
from core.evaluation_engine import evaluate_solution_candidate, EvaluationResult # Class for typed results
|
@@ -16,43 +20,32 @@ from prompts.prompt_templates import format_code_test_analysis_user_prompt
|
|
16 |
|
17 |
# --- Application Configuration (Models, Defaults) ---
|
18 |
AVAILABLE_MODELS_CONFIG = {}
|
19 |
-
UI_DEFAULT_MODEL_KEY = None
|
20 |
-
|
21 |
-
# --- Placeholder for the actual API model ID string ---
|
22 |
-
# You need to find the correct string from Google's documentation or AI Studio for this model.
|
23 |
-
# It might be something like "models/gemini-2.5-pro-preview-0506" or similar.
|
24 |
-
GEMINI_2_5_PRO_PREVIEW_MODEL_ID = "YOUR_GEMINI_2.5_PRO_PREVIEW_0506_MODEL_ID_STRING_HERE"
|
25 |
-
# Example: "gemini-experimental" or a more specific preview ID if available via API.
|
26 |
-
# For now, if you don't have the exact ID, you can use a known working one like "gemini-1.5-pro-latest"
|
27 |
-
# and then update this when you get the 2.5 Pro Preview ID.
|
28 |
-
# If GEMINI_2_5_PRO_PREVIEW_MODEL_ID remains the placeholder, that model won't work.
|
29 |
-
# Let's use a known one for now if the placeholder isn't replaced.
|
30 |
-
if GEMINI_2_5_PRO_PREVIEW_MODEL_ID == "YOUR_GEMINI_2.5_PRO_PREVIEW_0506_MODEL_ID_STRING_HERE":
|
31 |
-
print(f"WARNING: app.py - GEMINI_2_5_PRO_PREVIEW_MODEL_ID is a placeholder. Using 'gemini-1.5-pro-latest' as a stand-in for Gemini 2.5 Pro Preview.")
|
32 |
-
SAFE_GEMINI_PRO_ID = "gemini-1.5-pro-latest" # A known recent Pro model
|
33 |
-
else:
|
34 |
-
SAFE_GEMINI_PRO_ID = GEMINI_2_5_PRO_PREVIEW_MODEL_ID
|
35 |
|
|
|
|
|
|
|
|
|
36 |
|
37 |
# Populate with Gemini models first if API is configured
|
38 |
-
if
|
39 |
AVAILABLE_MODELS_CONFIG.update({
|
40 |
-
|
41 |
-
"Google Gemini
|
42 |
-
|
43 |
"Google Gemini 1.0 Pro (API - Legacy)": {"id": "gemini-1.0-pro-latest", "type": "google_gemini"},
|
44 |
})
|
45 |
-
# Prioritize
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
UI_DEFAULT_MODEL_KEY = "Google Gemini 1.5 Flash (API - Fast)"
|
50 |
print(f"INFO: app.py - Gemini models populated. Default set to: {UI_DEFAULT_MODEL_KEY}")
|
51 |
else:
|
52 |
-
print("WARNING: app.py - Gemini API not configured; Gemini models will be unavailable.")
|
53 |
|
54 |
-
# Populate with Hugging Face models if API is configured
|
55 |
-
if
|
56 |
AVAILABLE_MODELS_CONFIG.update({
|
57 |
"Google Gemma 2B (HF - Quick Test)": {"id": "google/gemma-2b-it", "type": "hf"},
|
58 |
"Mistral 7B Instruct (HF)": {"id": "mistralai/Mistral-7B-Instruct-v0.2", "type": "hf"},
|
@@ -64,44 +57,45 @@ if HF_API_CONFIGURED:
|
|
64 |
else:
|
65 |
print("INFO: app.py - HF models also populated as alternatives.")
|
66 |
else:
|
67 |
-
print("WARNING: app.py - Hugging Face API not configured; HF models will be unavailable.")
|
68 |
|
69 |
# Absolute fallback if no models could be configured at all
|
70 |
if not AVAILABLE_MODELS_CONFIG:
|
71 |
-
print("CRITICAL APP ERROR: No models could be configured. Check API keys in Space Secrets.")
|
72 |
-
AVAILABLE_MODELS_CONFIG["No Models Available (Check API Keys)"] = {"id": "dummy_error", "type": "none"}
|
73 |
-
UI_DEFAULT_MODEL_KEY = "No Models Available (Check API Keys)"
|
74 |
-
elif not UI_DEFAULT_MODEL_KEY and AVAILABLE_MODELS_CONFIG:
|
|
|
75 |
UI_DEFAULT_MODEL_KEY = list(AVAILABLE_MODELS_CONFIG.keys())[0]
|
76 |
print(f"WARNING: app.py - UI_DEFAULT_MODEL_KEY was not set by primary logic, falling back to first available: {UI_DEFAULT_MODEL_KEY}")
|
77 |
|
78 |
|
79 |
# --- Main Orchestration Logic for Gradio ---
|
80 |
-
# This function remains the same as in the previous "full rewrite" that included all files.
|
81 |
def run_algoforge_simulation_orchestrator(
|
82 |
-
problem_type_selected: str,
|
83 |
-
problem_description_text: str,
|
84 |
-
initial_hints_text: str,
|
85 |
user_provided_tests_code: str,
|
86 |
-
num_initial_solutions_to_gen: int,
|
87 |
selected_model_ui_key: str,
|
88 |
genesis_temp: float, genesis_max_tokens: int,
|
89 |
critique_temp: float, critique_max_tokens: int,
|
90 |
evolution_temp: float, evolution_max_tokens: int,
|
91 |
-
progress=gr.Progress(track_tqdm=True)
|
92 |
):
|
93 |
progress(0, desc="Initializing AlgoForge Prime™...")
|
94 |
log_entries = [f"**AlgoForge Prime™ Cycle Starting at {time.strftime('%Y-%m-%d %H:%M:%S')}**"]
|
95 |
start_time = time.time()
|
96 |
|
|
|
97 |
if not problem_description_text.strip():
|
98 |
-
error_msg = "CRITICAL INPUT ERROR: Problem Description is mandatory."
|
99 |
log_entries.append(error_msg)
|
100 |
-
return error_msg, "", "", "\n".join(log_entries), ""
|
101 |
|
102 |
current_model_config = AVAILABLE_MODELS_CONFIG.get(selected_model_ui_key)
|
103 |
if not current_model_config or current_model_config["type"] == "none":
|
104 |
-
error_msg = f"CRITICAL CONFIG ERROR: No valid LLM selected ('{selected_model_ui_key}'). API keys
|
105 |
log_entries.append(error_msg)
|
106 |
return error_msg, "", "", "\n".join(log_entries), ""
|
107 |
|
@@ -109,58 +103,72 @@ def run_algoforge_simulation_orchestrator(
|
|
109 |
log_entries.append(f"Problem Type: {problem_type_selected}")
|
110 |
log_entries.append(f"User Unit Tests Provided: {'Yes' if user_provided_tests_code.strip() else 'No'}")
|
111 |
|
|
|
112 |
llm_config_genesis = {"type": current_model_config["type"], "model_id": current_model_config["id"], "temp": genesis_temp, "max_tokens": genesis_max_tokens}
|
113 |
llm_config_critique = {"type": current_model_config["type"], "model_id": current_model_config["id"], "temp": critique_temp, "max_tokens": critique_max_tokens}
|
114 |
llm_config_evolution = {"type": current_model_config["type"], "model_id": current_model_config["id"], "temp": evolution_temp, "max_tokens": evolution_max_tokens}
|
115 |
|
116 |
-
# STAGE 1: GENESIS
|
117 |
-
progress(0.05, desc="Stage 1: Genesis Engine - Generating...")
|
118 |
log_entries.append("\n**------ STAGE 1: GENESIS ENGINE ------**")
|
|
|
119 |
initial_raw_solutions = generate_initial_solutions(
|
120 |
problem_description_text, initial_hints_text, problem_type_selected,
|
121 |
num_initial_solutions_to_gen, llm_config_genesis
|
122 |
)
|
123 |
-
log_entries.append(f"Genesis Engine produced {len(initial_raw_solutions)} raw candidate(s).")
|
124 |
-
for i, sol_text in enumerate(initial_raw_solutions):
|
125 |
-
log_entries.append(f" Candidate {i+1} (Raw Snippet): {str(sol_text)[:120]}...")
|
126 |
-
|
127 |
|
128 |
-
# STAGE 2: CRITIQUE & AUTOMATED EVALUATION
|
129 |
-
progress(0.25, desc="Stage 2: Critique Crucible - Evaluating...")
|
130 |
log_entries.append("\n**------ STAGE 2: CRITIQUE CRUCIBLE & AUTOMATED EVALUATION ------**")
|
131 |
-
|
|
|
|
|
132 |
for i, candidate_solution_text in enumerate(initial_raw_solutions):
|
133 |
-
current_progress = 0.25 + ((i + 1) / num_initial_solutions_to_gen) * 0.4 # Progress for evaluation
|
134 |
-
progress(current_progress, desc=f"Evaluating Candidate {i+1}...")
|
135 |
log_entries.append(f"\n--- Evaluating Candidate {i+1} ---")
|
136 |
-
|
137 |
-
|
|
|
|
|
138 |
user_provided_tests_code, llm_config_critique
|
139 |
)
|
140 |
-
|
141 |
-
"id": i + 1, "solution_text": candidate_solution_text, "evaluation_result": evaluation_obj
|
142 |
-
})
|
143 |
log_entries.append(f" Final Combined Score: {evaluation_obj.score}/10")
|
144 |
log_entries.append(f" Automated Tests: {evaluation_obj.passed_tests}/{evaluation_obj.total_tests} passed.")
|
145 |
if evaluation_obj.execution_summary: log_entries.append(f" Execution Summary: {evaluation_obj.execution_summary}")
|
146 |
log_entries.append(f" LLM Critique (Snippet): {str(evaluation_obj.critique_text)[:150]}...")
|
|
|
|
|
|
|
|
|
|
|
|
|
147 |
|
148 |
-
|
149 |
initial_solutions_display_markdown = []
|
150 |
-
for data in evaluated_candidates_list:
|
151 |
initial_solutions_display_markdown.append(
|
152 |
-
f"**Candidate {data['id']}:**\n
|
153 |
-
|
|
|
|
|
|
|
154 |
)
|
155 |
-
|
156 |
-
# STAGE 3: SELECTION OF CHAMPION
|
157 |
-
progress(0.7, desc="Stage 3: Selecting Champion...")
|
158 |
log_entries.append("\n**------ STAGE 3: CHAMPION SELECTION ------**")
|
|
|
159 |
potentially_viable_candidates = [
|
160 |
-
cand for cand in evaluated_candidates_list
|
161 |
if cand["evaluation_result"] and cand["evaluation_result"].score > 0 and \
|
162 |
-
cand["solution_text"] and not str(cand["solution_text"]).startswith("ERROR")
|
163 |
]
|
|
|
164 |
if not potentially_viable_candidates:
|
165 |
final_error_msg = "No viable candidate solutions found after generation and evaluation. All attempts may have failed or scored too low."
|
166 |
log_entries.append(f" CRITICAL: {final_error_msg}")
|
@@ -168,61 +176,75 @@ def run_algoforge_simulation_orchestrator(
|
|
168 |
|
169 |
potentially_viable_candidates.sort(key=lambda x: x["evaluation_result"].score, reverse=True)
|
170 |
champion_candidate_data = potentially_viable_candidates[0]
|
|
|
171 |
log_entries.append(f"Champion Selected: Candidate {champion_candidate_data['id']} "
|
172 |
-
f"(Solution Snippet: {str(champion_candidate_data['solution_text'])[:60]}...) "
|
173 |
f"with evaluation score {champion_candidate_data['evaluation_result'].score}/10.")
|
|
|
174 |
champion_display_markdown = (
|
175 |
f"**Champion Candidate ID: {champion_candidate_data['id']} "
|
176 |
f"(Original Combined Score: {champion_candidate_data['evaluation_result'].score}/10):**\n"
|
177 |
f"```python\n{champion_candidate_data['solution_text']}\n```\n\n"
|
178 |
-
f"**Original Comprehensive Evaluation for this Champion:**\n
|
|
|
179 |
)
|
180 |
|
181 |
-
# STAGE 4: EVOLUTIONARY FORGE
|
182 |
-
progress(0.75, desc="Stage 4: Evolutionary Forge - Refining...")
|
183 |
log_entries.append("\n**------ STAGE 4: EVOLUTIONARY FORGE ------**")
|
|
|
184 |
evolved_solution_code = evolve_solution(
|
185 |
-
str(champion_candidate_data["solution_text"]),
|
186 |
-
str(champion_candidate_data["evaluation_result"].critique_text),
|
187 |
champion_candidate_data["evaluation_result"].score,
|
188 |
-
problem_description_text,
|
|
|
|
|
189 |
)
|
190 |
log_entries.append(f"Raw Evolved Solution Text (Snippet): {str(evolved_solution_code)[:150]}...")
|
|
|
191 |
evolved_solution_display_markdown = ""
|
192 |
-
ai_test_analysis_markdown = ""
|
193 |
|
194 |
-
if str(evolved_solution_code).startswith("ERROR"):
|
195 |
evolved_solution_display_markdown = f"**Evolution Stage Failed:**\n{evolved_solution_code}"
|
196 |
else:
|
197 |
evolved_solution_display_markdown = f"**✨ AlgoForge Prime™ Evolved Artifact ✨:**\n```python\n{evolved_solution_code}\n```"
|
|
|
198 |
if "python" in problem_type_selected.lower() and user_provided_tests_code.strip():
|
199 |
-
progress(0.9, desc="Post-Evolution:
|
200 |
log_entries.append("\n--- Post-Evolution Sanity Check (Automated Tests on Evolved Code) ---")
|
|
|
201 |
evolved_critique_config = {"type": current_model_config["type"], "model_id": current_model_config["id"], "temp": 0.2, "max_tokens": critique_max_tokens}
|
202 |
-
|
203 |
-
|
|
|
204 |
user_provided_tests_code, evolved_critique_config
|
205 |
)
|
|
|
206 |
evolved_solution_display_markdown += (
|
207 |
f"\n\n**Post-Evolution Automated Test Results (Simulated):**\n"
|
208 |
-
f"{evolved_code_eval_result.execution_summary}\n"
|
209 |
f"Passed: {evolved_code_eval_result.passed_tests}/{evolved_code_eval_result.total_tests}\n"
|
210 |
)
|
211 |
log_entries.append(f" Evolved Code Test Results: {evolved_code_eval_result.passed_tests}/{evolved_code_eval_result.total_tests} passed. "
|
212 |
f"Summary: {evolved_code_eval_result.execution_summary}")
|
213 |
|
214 |
-
if evolved_code_eval_result.total_tests > 0 :
|
215 |
progress(0.95, desc="Post-Evolution: AI Analyzing Test Results...")
|
216 |
log_entries.append("\n--- AI Analysis of Evolved Code's Test Results ---")
|
217 |
analysis_user_prompt = format_code_test_analysis_user_prompt(
|
218 |
-
str(evolved_solution_code),
|
219 |
-
|
|
|
220 |
)
|
221 |
analysis_system_prompt = get_system_prompt("code_execution_explainer")
|
222 |
-
llm_analysis_config = {"type": current_model_config["type"], "model_id": current_model_config["id"],
|
223 |
-
"temp": 0.3, "max_tokens": critique_max_tokens + 150} # Ensure enough tokens for analysis
|
224 |
|
225 |
-
|
|
|
|
|
|
|
|
|
226 |
explanation_response_obj = None
|
227 |
if llm_analysis_config["type"] == "hf":
|
228 |
explanation_response_obj = call_huggingface_api(analysis_user_prompt, llm_analysis_config["model_id"], llm_analysis_config["temp"], llm_analysis_config["max_tokens"], analysis_system_prompt)
|
@@ -245,8 +267,8 @@ def run_algoforge_simulation_orchestrator(
|
|
245 |
|
246 |
# --- Gradio UI Definition ---
|
247 |
intro_markdown = """
|
248 |
-
# ✨ AlgoForge Prime™ ✨: Modular Algorithmic Evolution (
|
249 |
-
This version prioritizes
|
250 |
featuring (simulated) unit testing for Python code if provided.
|
251 |
|
252 |
**API Keys Required in Space Secrets (should be working):**
|
@@ -255,70 +277,88 @@ featuring (simulated) unit testing for Python code if provided.
|
|
255 |
"""
|
256 |
|
257 |
ui_token_status_md = ""
|
258 |
-
if not
|
259 |
ui_token_status_md = "<p style='color:red;'>⚠️ **CRITICAL: NEITHER GOOGLE_API_KEY NOR HF_TOKEN are configured or working correctly.** The application will not be able to call any LLMs.</p>"
|
260 |
else:
|
261 |
-
if
|
262 |
else: ui_token_status_md += "<p style='color:orange;'>⚠️ **GOOGLE_API_KEY missing or failed to configure.** Gemini API models will be disabled.</p>"
|
263 |
-
if
|
264 |
else: ui_token_status_md += "<p style='color:orange;'>⚠️ **HF_TOKEN missing or client failed to initialize.** Hugging Face models will be disabled.</p>"
|
265 |
|
266 |
|
267 |
-
with gr.Blocks(theme=gr.themes.Soft(primary_hue="
|
268 |
gr.Markdown(intro_markdown)
|
269 |
gr.HTML(ui_token_status_md)
|
270 |
|
271 |
-
|
272 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
273 |
else:
|
274 |
with gr.Row():
|
275 |
-
|
|
|
276 |
gr.Markdown("## 💡 1. Define the Challenge")
|
277 |
problem_type_dropdown = gr.Dropdown(
|
278 |
choices=["Python Algorithm with Tests", "Python Algorithm (Critique Only)", "General Algorithm Idea", "Conceptual System Design", "Pseudocode Refinement"],
|
279 |
label="Type of Problem / Algorithm", value="Python Algorithm with Tests",
|
280 |
-
info="Select '...with Tests' to enable (simulated) unit testing."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
281 |
)
|
282 |
-
problem_description_textbox = gr.Textbox(lines=5, label="Problem Description / Desired Outcome", placeholder="Describe the algorithmic task clearly.")
|
283 |
-
initial_hints_textbox = gr.Textbox(lines=3, label="Initial Thoughts / Constraints (Optional)", placeholder="Any specific approaches or limitations.")
|
284 |
-
user_tests_textbox = gr.Textbox(lines=6, label="Python Unit Tests (Optional, one `assert` per line)", placeholder="assert function_name(input) == expected_output")
|
285 |
|
286 |
gr.Markdown("## ⚙️ 2. Configure The Forge")
|
287 |
model_selection_dropdown = gr.Dropdown(
|
288 |
choices=list(AVAILABLE_MODELS_CONFIG.keys()),
|
289 |
-
value=UI_DEFAULT_MODEL_KEY,
|
290 |
label="Select LLM Core Model",
|
291 |
-
info="Ensure the corresponding API key is working."
|
292 |
)
|
293 |
-
num_initial_solutions_slider = gr.Slider(minimum=1, maximum=3, value=2, step=1, label="Number of Initial Solutions") # Max 3 for faster
|
294 |
|
295 |
with gr.Accordion("Advanced LLM Parameters (Expert Users)", open=False):
|
296 |
with gr.Row():
|
297 |
-
genesis_temp_slider = gr.Slider(minimum=0.0, maximum=1.0, value=0.7, step=0.05, label="Genesis Temp")
|
298 |
-
genesis_max_tokens_slider = gr.Slider(minimum=256, maximum=4096, value=1024, step=128, label="Genesis Max Tokens")
|
299 |
with gr.Row():
|
300 |
critique_temp_slider = gr.Slider(minimum=0.0, maximum=1.0, value=0.4, step=0.05, label="Critique Temp")
|
301 |
-
critique_max_tokens_slider = gr.Slider(minimum=150, maximum=2048, value=512, step=64, label="Critique Max Tokens")
|
302 |
with gr.Row():
|
303 |
evolution_temp_slider = gr.Slider(minimum=0.0, maximum=1.0, value=0.75, step=0.05, label="Evolution Temp")
|
304 |
-
evolution_max_tokens_slider = gr.Slider(minimum=256, maximum=4096, value=1536, step=128, label="Evolution Max Tokens")
|
305 |
|
|
|
306 |
|
307 |
-
|
308 |
-
|
309 |
-
with gr.Column(scale=3):
|
310 |
gr.Markdown("## 🔥 3. The Forge's Output")
|
311 |
-
with gr.Tabs():
|
312 |
-
with gr.TabItem("📜 Initial Candidates & Evaluations"):
|
313 |
-
output_initial_solutions_markdown = gr.Markdown()
|
314 |
-
with gr.TabItem("🏆 Champion Candidate"):
|
315 |
-
output_champion_markdown = gr.Markdown()
|
316 |
-
with gr.TabItem("🌟 Evolved Artifact & Test Analysis"):
|
317 |
-
output_evolved_markdown = gr.Markdown()
|
318 |
-
output_ai_test_analysis_markdown = gr.Markdown()
|
319 |
-
with gr.TabItem("🛠️ Interaction Log"):
|
320 |
-
output_interaction_log_markdown = gr.Markdown()
|
321 |
|
|
|
322 |
engage_button.click(
|
323 |
fn=run_algoforge_simulation_orchestrator,
|
324 |
inputs=[
|
@@ -331,23 +371,29 @@ with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", secondary_hue="sky"), ti
|
|
331 |
outputs=[
|
332 |
output_initial_solutions_markdown, output_champion_markdown,
|
333 |
output_evolved_markdown, output_interaction_log_markdown,
|
334 |
-
output_ai_test_analysis_markdown
|
335 |
]
|
336 |
)
|
|
|
337 |
gr.Markdown("---")
|
338 |
gr.Markdown(
|
339 |
-
"**Disclaimer:**
|
|
|
|
|
|
|
|
|
340 |
)
|
341 |
|
342 |
# --- Entry Point for Running the Gradio App ---
|
343 |
if __name__ == "__main__":
|
344 |
print("="*80)
|
345 |
-
print("AlgoForge Prime™ (Modular Version
|
346 |
-
|
347 |
-
print(f"
|
348 |
-
|
349 |
-
|
|
|
350 |
print(f" UI Default Model Key: {UI_DEFAULT_MODEL_KEY}")
|
351 |
print(f" Available models for UI: {list(AVAILABLE_MODELS_CONFIG.keys())}")
|
352 |
print("="*80)
|
353 |
-
app_demo.launch(debug=True, server_name="0.0.0.0")
|
|
|
5 |
|
6 |
# --- Core Logic Imports ---
|
7 |
# Initialize clients first to ensure API keys are loaded before other modules use them.
|
8 |
+
from core.llm_clients import initialize_all_clients, is_gemini_api_configured, is_hf_api_configured # Use getters
|
9 |
+
initialize_all_clients() # CRITICAL: Call initialization first
|
10 |
+
|
11 |
+
# Now get the status AFTER initialization
|
12 |
+
GEMINI_API_READY = is_gemini_api_configured()
|
13 |
+
HF_API_READY = is_hf_api_configured()
|
14 |
|
15 |
from core.generation_engine import generate_initial_solutions
|
16 |
from core.evaluation_engine import evaluate_solution_candidate, EvaluationResult # Class for typed results
|
|
|
20 |
|
21 |
# --- Application Configuration (Models, Defaults) ---
|
22 |
AVAILABLE_MODELS_CONFIG = {}
|
23 |
+
UI_DEFAULT_MODEL_KEY = None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
24 |
|
25 |
+
# Define Gemini 1.5 model IDs (use the exact strings from Google's documentation)
|
26 |
+
# These are common aliases; specific versioned IDs might also be available.
|
27 |
+
GEMINI_1_5_PRO_LATEST_ID = "gemini-1.5-pro-latest"
|
28 |
+
GEMINI_1_5_FLASH_LATEST_ID = "gemini-1.5-flash-latest"
|
29 |
|
30 |
# Populate with Gemini models first if API is configured
|
31 |
+
if GEMINI_API_READY:
|
32 |
AVAILABLE_MODELS_CONFIG.update({
|
33 |
+
f"Google Gemini 1.5 Pro (API - Recommended)": {"id": GEMINI_1_5_PRO_LATEST_ID, "type": "google_gemini"},
|
34 |
+
f"Google Gemini 1.5 Flash (API - Fast)": {"id": GEMINI_1_5_FLASH_LATEST_ID, "type": "google_gemini"},
|
35 |
+
# You can add older Gemini versions here if needed
|
36 |
"Google Gemini 1.0 Pro (API - Legacy)": {"id": "gemini-1.0-pro-latest", "type": "google_gemini"},
|
37 |
})
|
38 |
+
# Prioritize 1.5 Pro as default
|
39 |
+
UI_DEFAULT_MODEL_KEY = f"Google Gemini 1.5 Pro (API - Recommended)"
|
40 |
+
# Fallback to Flash if Pro key somehow isn't in dict (shouldn't happen with this logic)
|
41 |
+
if UI_DEFAULT_MODEL_KEY not in AVAILABLE_MODELS_CONFIG: # Should not be needed if Pro ID is valid
|
42 |
+
UI_DEFAULT_MODEL_KEY = f"Google Gemini 1.5 Flash (API - Fast)"
|
43 |
print(f"INFO: app.py - Gemini models populated. Default set to: {UI_DEFAULT_MODEL_KEY}")
|
44 |
else:
|
45 |
+
print("WARNING: app.py - Gemini API not configured (checked via getter); Gemini models will be unavailable.")
|
46 |
|
47 |
+
# Populate with Hugging Face models if API is configured
|
48 |
+
if HF_API_READY:
|
49 |
AVAILABLE_MODELS_CONFIG.update({
|
50 |
"Google Gemma 2B (HF - Quick Test)": {"id": "google/gemma-2b-it", "type": "hf"},
|
51 |
"Mistral 7B Instruct (HF)": {"id": "mistralai/Mistral-7B-Instruct-v0.2", "type": "hf"},
|
|
|
57 |
else:
|
58 |
print("INFO: app.py - HF models also populated as alternatives.")
|
59 |
else:
|
60 |
+
print("WARNING: app.py - Hugging Face API not configured (checked via getter); HF models will be unavailable.")
|
61 |
|
62 |
# Absolute fallback if no models could be configured at all
|
63 |
if not AVAILABLE_MODELS_CONFIG:
|
64 |
+
print("CRITICAL APP ERROR: No models could be configured. Check API keys in Space Secrets and restart Space.")
|
65 |
+
AVAILABLE_MODELS_CONFIG["No Models Available (Check API Keys & Restart)"] = {"id": "dummy_error", "type": "none"}
|
66 |
+
UI_DEFAULT_MODEL_KEY = "No Models Available (Check API Keys & Restart)"
|
67 |
+
elif not UI_DEFAULT_MODEL_KEY and AVAILABLE_MODELS_CONFIG: # Should not happen if logic above is correct
|
68 |
+
# If somehow UI_DEFAULT_MODEL_KEY is still None, pick the first available model
|
69 |
UI_DEFAULT_MODEL_KEY = list(AVAILABLE_MODELS_CONFIG.keys())[0]
|
70 |
print(f"WARNING: app.py - UI_DEFAULT_MODEL_KEY was not set by primary logic, falling back to first available: {UI_DEFAULT_MODEL_KEY}")
|
71 |
|
72 |
|
73 |
# --- Main Orchestration Logic for Gradio ---
|
|
|
74 |
def run_algoforge_simulation_orchestrator(
|
75 |
+
problem_type_selected: str,
|
76 |
+
problem_description_text: str,
|
77 |
+
initial_hints_text: str,
|
78 |
user_provided_tests_code: str,
|
79 |
+
num_initial_solutions_to_gen: int,
|
80 |
selected_model_ui_key: str,
|
81 |
genesis_temp: float, genesis_max_tokens: int,
|
82 |
critique_temp: float, critique_max_tokens: int,
|
83 |
evolution_temp: float, evolution_max_tokens: int,
|
84 |
+
progress=gr.Progress(track_tqdm=True) # Gradio progress tracker
|
85 |
):
|
86 |
progress(0, desc="Initializing AlgoForge Prime™...")
|
87 |
log_entries = [f"**AlgoForge Prime™ Cycle Starting at {time.strftime('%Y-%m-%d %H:%M:%S')}**"]
|
88 |
start_time = time.time()
|
89 |
|
90 |
+
# Basic input validation
|
91 |
if not problem_description_text.strip():
|
92 |
+
error_msg = "CRITICAL INPUT ERROR: Problem Description is mandatory. Please describe the problem."
|
93 |
log_entries.append(error_msg)
|
94 |
+
return error_msg, "", "", "\n".join(log_entries), "" # Return 5 values for outputs
|
95 |
|
96 |
current_model_config = AVAILABLE_MODELS_CONFIG.get(selected_model_ui_key)
|
97 |
if not current_model_config or current_model_config["type"] == "none":
|
98 |
+
error_msg = f"CRITICAL CONFIG ERROR: No valid LLM selected ('{selected_model_ui_key}'). This usually means API keys are missing or failed to initialize. Check Space Secrets and restart."
|
99 |
log_entries.append(error_msg)
|
100 |
return error_msg, "", "", "\n".join(log_entries), ""
|
101 |
|
|
|
103 |
log_entries.append(f"Problem Type: {problem_type_selected}")
|
104 |
log_entries.append(f"User Unit Tests Provided: {'Yes' if user_provided_tests_code.strip() else 'No'}")
|
105 |
|
106 |
+
# Prepare LLM configurations for each stage
|
107 |
llm_config_genesis = {"type": current_model_config["type"], "model_id": current_model_config["id"], "temp": genesis_temp, "max_tokens": genesis_max_tokens}
|
108 |
llm_config_critique = {"type": current_model_config["type"], "model_id": current_model_config["id"], "temp": critique_temp, "max_tokens": critique_max_tokens}
|
109 |
llm_config_evolution = {"type": current_model_config["type"], "model_id": current_model_config["id"], "temp": evolution_temp, "max_tokens": evolution_max_tokens}
|
110 |
|
111 |
+
# --- STAGE 1: GENESIS ---
|
112 |
+
progress(0.05, desc="Stage 1: Genesis Engine - Generating Solutions...")
|
113 |
log_entries.append("\n**------ STAGE 1: GENESIS ENGINE ------**")
|
114 |
+
|
115 |
initial_raw_solutions = generate_initial_solutions(
|
116 |
problem_description_text, initial_hints_text, problem_type_selected,
|
117 |
num_initial_solutions_to_gen, llm_config_genesis
|
118 |
)
|
119 |
+
log_entries.append(f"Genesis Engine produced {len(initial_raw_solutions)} raw solution candidate(s).")
|
120 |
+
for i, sol_text in enumerate(initial_raw_solutions):
|
121 |
+
log_entries.append(f" Candidate {i+1} (Raw Snippet): {str(sol_text)[:120]}...") # str() for safety
|
|
|
122 |
|
123 |
+
# --- STAGE 2: CRITIQUE & AUTOMATED EVALUATION ---
|
124 |
+
progress(0.25, desc="Stage 2: Critique Crucible - Evaluating Candidates...")
|
125 |
log_entries.append("\n**------ STAGE 2: CRITIQUE CRUCIBLE & AUTOMATED EVALUATION ------**")
|
126 |
+
|
127 |
+
evaluated_candidates_list = [] # Stores dicts: {"id": ..., "solution_text": ..., "evaluation_result": EvaluationResult}
|
128 |
+
|
129 |
for i, candidate_solution_text in enumerate(initial_raw_solutions):
|
130 |
+
current_progress = 0.25 + ( (i + 1) / num_initial_solutions_to_gen ) * 0.4 # Progress for evaluation stage
|
131 |
+
progress(current_progress, desc=f"Evaluating Candidate {i+1} of {num_initial_solutions_to_gen}...")
|
132 |
log_entries.append(f"\n--- Evaluating Candidate {i+1} ---")
|
133 |
+
|
134 |
+
evaluation_obj = evaluate_solution_candidate( # type: EvaluationResult
|
135 |
+
str(candidate_solution_text), # Ensure it's a string before passing
|
136 |
+
problem_description_text, problem_type_selected,
|
137 |
user_provided_tests_code, llm_config_critique
|
138 |
)
|
139 |
+
|
|
|
|
|
140 |
log_entries.append(f" Final Combined Score: {evaluation_obj.score}/10")
|
141 |
log_entries.append(f" Automated Tests: {evaluation_obj.passed_tests}/{evaluation_obj.total_tests} passed.")
|
142 |
if evaluation_obj.execution_summary: log_entries.append(f" Execution Summary: {evaluation_obj.execution_summary}")
|
143 |
log_entries.append(f" LLM Critique (Snippet): {str(evaluation_obj.critique_text)[:150]}...")
|
144 |
+
|
145 |
+
evaluated_candidates_list.append({
|
146 |
+
"id": i + 1,
|
147 |
+
"solution_text": str(candidate_solution_text),
|
148 |
+
"evaluation_result": evaluation_obj
|
149 |
+
})
|
150 |
|
151 |
+
# Format display for initial solutions & evaluations
|
152 |
initial_solutions_display_markdown = []
|
153 |
+
for data in evaluated_candidates_list:
|
154 |
initial_solutions_display_markdown.append(
|
155 |
+
f"**Candidate {data['id']}:**\n"
|
156 |
+
# Assuming python for display, adjust if problem_type varies widely in output format
|
157 |
+
f"```python\n{data['solution_text']}\n```\n\n"
|
158 |
+
f"**Evaluation Verdict (Combined Score: {data['evaluation_result'].score}/10):**\n"
|
159 |
+
f"{data['evaluation_result'].critique_text}\n---"
|
160 |
)
|
161 |
+
|
162 |
+
# --- STAGE 3: SELECTION OF CHAMPION ---
|
163 |
+
progress(0.7, desc="Stage 3: Selecting Champion Candidate...")
|
164 |
log_entries.append("\n**------ STAGE 3: CHAMPION SELECTION ------**")
|
165 |
+
|
166 |
potentially_viable_candidates = [
|
167 |
+
cand for cand in evaluated_candidates_list
|
168 |
if cand["evaluation_result"] and cand["evaluation_result"].score > 0 and \
|
169 |
+
cand["solution_text"] and not str(cand["solution_text"]).startswith("ERROR")
|
170 |
]
|
171 |
+
|
172 |
if not potentially_viable_candidates:
|
173 |
final_error_msg = "No viable candidate solutions found after generation and evaluation. All attempts may have failed or scored too low."
|
174 |
log_entries.append(f" CRITICAL: {final_error_msg}")
|
|
|
176 |
|
177 |
potentially_viable_candidates.sort(key=lambda x: x["evaluation_result"].score, reverse=True)
|
178 |
champion_candidate_data = potentially_viable_candidates[0]
|
179 |
+
|
180 |
log_entries.append(f"Champion Selected: Candidate {champion_candidate_data['id']} "
|
181 |
+
f"(Solution Snippet: {str(champion_candidate_data['solution_text'])[:60]}...) "
|
182 |
f"with evaluation score {champion_candidate_data['evaluation_result'].score}/10.")
|
183 |
+
|
184 |
champion_display_markdown = (
|
185 |
f"**Champion Candidate ID: {champion_candidate_data['id']} "
|
186 |
f"(Original Combined Score: {champion_candidate_data['evaluation_result'].score}/10):**\n"
|
187 |
f"```python\n{champion_candidate_data['solution_text']}\n```\n\n"
|
188 |
+
f"**Original Comprehensive Evaluation for this Champion:**\n"
|
189 |
+
f"{champion_candidate_data['evaluation_result'].critique_text}"
|
190 |
)
|
191 |
|
192 |
+
# --- STAGE 4: EVOLUTIONARY FORGE ---
|
193 |
+
progress(0.75, desc="Stage 4: Evolutionary Forge - Refining Champion...")
|
194 |
log_entries.append("\n**------ STAGE 4: EVOLUTIONARY FORGE ------**")
|
195 |
+
|
196 |
evolved_solution_code = evolve_solution(
|
197 |
+
str(champion_candidate_data["solution_text"]),
|
198 |
+
str(champion_candidate_data["evaluation_result"].critique_text),
|
199 |
champion_candidate_data["evaluation_result"].score,
|
200 |
+
problem_description_text,
|
201 |
+
problem_type_selected,
|
202 |
+
llm_config_evolution
|
203 |
)
|
204 |
log_entries.append(f"Raw Evolved Solution Text (Snippet): {str(evolved_solution_code)[:150]}...")
|
205 |
+
|
206 |
evolved_solution_display_markdown = ""
|
207 |
+
ai_test_analysis_markdown = ""
|
208 |
|
209 |
+
if str(evolved_solution_code).startswith("ERROR"):
|
210 |
evolved_solution_display_markdown = f"**Evolution Stage Failed:**\n{evolved_solution_code}"
|
211 |
else:
|
212 |
evolved_solution_display_markdown = f"**✨ AlgoForge Prime™ Evolved Artifact ✨:**\n```python\n{evolved_solution_code}\n```"
|
213 |
+
|
214 |
if "python" in problem_type_selected.lower() and user_provided_tests_code.strip():
|
215 |
+
progress(0.9, desc="Post-Evolution: Re-running Automated Tests on Evolved Code...")
|
216 |
log_entries.append("\n--- Post-Evolution Sanity Check (Automated Tests on Evolved Code) ---")
|
217 |
+
|
218 |
evolved_critique_config = {"type": current_model_config["type"], "model_id": current_model_config["id"], "temp": 0.2, "max_tokens": critique_max_tokens}
|
219 |
+
|
220 |
+
evolved_code_eval_result = evaluate_solution_candidate(
|
221 |
+
str(evolved_solution_code), problem_description_text, problem_type_selected,
|
222 |
user_provided_tests_code, evolved_critique_config
|
223 |
)
|
224 |
+
|
225 |
evolved_solution_display_markdown += (
|
226 |
f"\n\n**Post-Evolution Automated Test Results (Simulated):**\n"
|
227 |
+
f"{evolved_code_eval_result.execution_summary}\n" # This now comes from EvaluationResult
|
228 |
f"Passed: {evolved_code_eval_result.passed_tests}/{evolved_code_eval_result.total_tests}\n"
|
229 |
)
|
230 |
log_entries.append(f" Evolved Code Test Results: {evolved_code_eval_result.passed_tests}/{evolved_code_eval_result.total_tests} passed. "
|
231 |
f"Summary: {evolved_code_eval_result.execution_summary}")
|
232 |
|
233 |
+
if evolved_code_eval_result.total_tests > 0 :
|
234 |
progress(0.95, desc="Post-Evolution: AI Analyzing Test Results...")
|
235 |
log_entries.append("\n--- AI Analysis of Evolved Code's Test Results ---")
|
236 |
analysis_user_prompt = format_code_test_analysis_user_prompt(
|
237 |
+
str(evolved_solution_code),
|
238 |
+
user_provided_tests_code,
|
239 |
+
str(evolved_code_eval_result.execution_summary)
|
240 |
)
|
241 |
analysis_system_prompt = get_system_prompt("code_execution_explainer")
|
|
|
|
|
242 |
|
243 |
+
llm_analysis_config = {"type": current_model_config["type"], "model_id": current_model_config["id"],
|
244 |
+
"temp": 0.3, "max_tokens": critique_max_tokens + 150}
|
245 |
+
|
246 |
+
from core.llm_clients import call_huggingface_api, call_gemini_api
|
247 |
+
|
248 |
explanation_response_obj = None
|
249 |
if llm_analysis_config["type"] == "hf":
|
250 |
explanation_response_obj = call_huggingface_api(analysis_user_prompt, llm_analysis_config["model_id"], llm_analysis_config["temp"], llm_analysis_config["max_tokens"], analysis_system_prompt)
|
|
|
267 |
|
268 |
# --- Gradio UI Definition ---
|
269 |
intro_markdown = """
|
270 |
+
# ✨ AlgoForge Prime™ ✨: Modular Algorithmic Evolution (v1.5 Gemini Focus)
|
271 |
+
This version prioritizes Google Gemini 1.5 models and demonstrates a conceptual workflow for AI-assisted algorithm discovery,
|
272 |
featuring (simulated) unit testing for Python code if provided.
|
273 |
|
274 |
**API Keys Required in Space Secrets (should be working):**
|
|
|
277 |
"""
|
278 |
|
279 |
ui_token_status_md = ""
|
280 |
+
if not GEMINI_API_READY and not HF_API_READY: # Use status from getters
|
281 |
ui_token_status_md = "<p style='color:red;'>⚠️ **CRITICAL: NEITHER GOOGLE_API_KEY NOR HF_TOKEN are configured or working correctly.** The application will not be able to call any LLMs.</p>"
|
282 |
else:
|
283 |
+
if GEMINI_API_READY: ui_token_status_md += "<p style='color:green;'>✅ Google Gemini API Key detected and configured.</p>"
|
284 |
else: ui_token_status_md += "<p style='color:orange;'>⚠️ **GOOGLE_API_KEY missing or failed to configure.** Gemini API models will be disabled.</p>"
|
285 |
+
if HF_API_READY: ui_token_status_md += "<p style='color:green;'>✅ Hugging Face API Token detected and client initialized.</p>"
|
286 |
else: ui_token_status_md += "<p style='color:orange;'>⚠️ **HF_TOKEN missing or client failed to initialize.** Hugging Face models will be disabled.</p>"
|
287 |
|
288 |
|
289 |
+
with gr.Blocks(theme=gr.themes.Soft(primary_hue="green", secondary_hue="lime"), title="AlgoForge Prime™ (1.5 Focus)") as app_demo:
|
290 |
gr.Markdown(intro_markdown)
|
291 |
gr.HTML(ui_token_status_md)
|
292 |
|
293 |
+
# Check if any models are actually usable based on API readiness
|
294 |
+
usable_models_available = any(
|
295 |
+
AVAILABLE_MODELS_CONFIG.get(key, {}).get("type") != "none"
|
296 |
+
for key in AVAILABLE_MODELS_CONFIG
|
297 |
+
)
|
298 |
+
|
299 |
+
if not usable_models_available:
|
300 |
+
gr.Markdown("<h2 style='color:red;'>No LLM models are available for use. Please ensure at least one API key (Google or Hugging Face) is correctly set in this Space's Secrets and that the Space has been restarted.</h2>")
|
301 |
else:
|
302 |
with gr.Row():
|
303 |
+
# Input Column
|
304 |
+
with gr.Column(scale=2):
|
305 |
gr.Markdown("## 💡 1. Define the Challenge")
|
306 |
problem_type_dropdown = gr.Dropdown(
|
307 |
choices=["Python Algorithm with Tests", "Python Algorithm (Critique Only)", "General Algorithm Idea", "Conceptual System Design", "Pseudocode Refinement"],
|
308 |
label="Type of Problem / Algorithm", value="Python Algorithm with Tests",
|
309 |
+
info="Select '...with Tests' to enable (simulated) unit testing if you provide tests below."
|
310 |
+
)
|
311 |
+
problem_description_textbox = gr.Textbox(
|
312 |
+
lines=5, label="Problem Description / Desired Outcome",
|
313 |
+
placeholder="Example for 'Python Algorithm with Tests':\n`def calculate_factorial(n: int) -> int:`\nCalculates factorial of n. Should handle n=0 (returns 1) and raise ValueError for n<0."
|
314 |
+
)
|
315 |
+
initial_hints_textbox = gr.Textbox(
|
316 |
+
lines=3, label="Initial Thoughts / Constraints (Optional)",
|
317 |
+
placeholder="E.g., 'Prefer an iterative solution over recursive for factorial.' or 'Consider time complexity.'"
|
318 |
+
)
|
319 |
+
user_tests_textbox = gr.Textbox(
|
320 |
+
lines=6, label="Python Unit Tests (Optional, one `assert` per line)",
|
321 |
+
placeholder="assert calculate_factorial(0) == 1\nassert calculate_factorial(5) == 120\n# For expected errors (advanced, not fully simulated here):\n# try:\n# calculate_factorial(-1)\n# assert False, \"ValueError not raised\"\n# except ValueError:\n# assert True",
|
322 |
+
info="For 'Python Algorithm with Tests'. Ensure function names match your problem description."
|
323 |
)
|
|
|
|
|
|
|
324 |
|
325 |
gr.Markdown("## ⚙️ 2. Configure The Forge")
|
326 |
model_selection_dropdown = gr.Dropdown(
|
327 |
choices=list(AVAILABLE_MODELS_CONFIG.keys()),
|
328 |
+
value=UI_DEFAULT_MODEL_KEY if UI_DEFAULT_MODEL_KEY in AVAILABLE_MODELS_CONFIG else (list(AVAILABLE_MODELS_CONFIG.keys())[0] if AVAILABLE_MODELS_CONFIG else None),
|
329 |
label="Select LLM Core Model",
|
330 |
+
info="Ensure the corresponding API key (Google or HF) is configured and working."
|
331 |
)
|
332 |
+
num_initial_solutions_slider = gr.Slider(minimum=1, maximum=3, value=2, step=1, label="Number of Initial Solutions (Genesis Engine)") # Max 3 for faster runs
|
333 |
|
334 |
with gr.Accordion("Advanced LLM Parameters (Expert Users)", open=False):
|
335 |
with gr.Row():
|
336 |
+
genesis_temp_slider = gr.Slider(minimum=0.0, maximum=1.0, value=0.7, step=0.05, label="Genesis Temp", info="Higher = more creative, Lower = more deterministic.")
|
337 |
+
genesis_max_tokens_slider = gr.Slider(minimum=256, maximum=4096, value=1024, step=128, label="Genesis Max Output Tokens")
|
338 |
with gr.Row():
|
339 |
critique_temp_slider = gr.Slider(minimum=0.0, maximum=1.0, value=0.4, step=0.05, label="Critique Temp")
|
340 |
+
critique_max_tokens_slider = gr.Slider(minimum=150, maximum=2048, value=512, step=64, label="Critique Max Output Tokens")
|
341 |
with gr.Row():
|
342 |
evolution_temp_slider = gr.Slider(minimum=0.0, maximum=1.0, value=0.75, step=0.05, label="Evolution Temp")
|
343 |
+
evolution_max_tokens_slider = gr.Slider(minimum=256, maximum=4096, value=1536, step=128, label="Evolution Max Output Tokens")
|
344 |
|
345 |
+
engage_button = gr.Button("🚀 ENGAGE ALGOFORGE PRIME™ 🚀", variant="primary", size="lg", elem_id="engage_button_elem")
|
346 |
|
347 |
+
# Output Column
|
348 |
+
with gr.Column(scale=3):
|
|
|
349 |
gr.Markdown("## 🔥 3. The Forge's Output")
|
350 |
+
with gr.Tabs(elem_id="output_tabs_elem"):
|
351 |
+
with gr.TabItem("📜 Initial Candidates & Evaluations", id="tab_initial_evals"):
|
352 |
+
output_initial_solutions_markdown = gr.Markdown(label="Generated Solutions & Combined Evaluations")
|
353 |
+
with gr.TabItem("🏆 Champion Candidate (Pre-Evolution)", id="tab_champion"):
|
354 |
+
output_champion_markdown = gr.Markdown(label="Top Pick for Refinement")
|
355 |
+
with gr.TabItem("🌟 Evolved Artifact & Test Analysis", id="tab_evolved"):
|
356 |
+
output_evolved_markdown = gr.Markdown(label="Refined Solution from Evolutionary Forge")
|
357 |
+
output_ai_test_analysis_markdown = gr.Markdown(label="AI Analysis of Evolved Code's Test Performance")
|
358 |
+
with gr.TabItem("🛠️ Interaction Log (Developer View)", id="tab_log"):
|
359 |
+
output_interaction_log_markdown = gr.Markdown(label="Detailed Log of LLM Prompts & Responses")
|
360 |
|
361 |
+
# Connect button to the orchestration function
|
362 |
engage_button.click(
|
363 |
fn=run_algoforge_simulation_orchestrator,
|
364 |
inputs=[
|
|
|
371 |
outputs=[
|
372 |
output_initial_solutions_markdown, output_champion_markdown,
|
373 |
output_evolved_markdown, output_interaction_log_markdown,
|
374 |
+
output_ai_test_analysis_markdown # Matched to the 5 outputs of orchestrator
|
375 |
]
|
376 |
)
|
377 |
+
|
378 |
gr.Markdown("---")
|
379 |
gr.Markdown(
|
380 |
+
"**Disclaimer:** This is a conceptual, educational demonstration. "
|
381 |
+
"The (simulated) unit testing feature is for illustrative purposes. "
|
382 |
+
"**NEVER run LLM-generated code from an untrusted source in an unrestricted environment.** "
|
383 |
+
"Implementing robust and secure code sandboxing is complex and absolutely critical for safety in real-world applications. "
|
384 |
+
"LLM outputs always require careful human review and verification."
|
385 |
)
|
386 |
|
387 |
# --- Entry Point for Running the Gradio App ---
|
388 |
if __name__ == "__main__":
|
389 |
print("="*80)
|
390 |
+
print("AlgoForge Prime™ (Modular Version - Gemini 1.5 Focus) - Launching...")
|
391 |
+
# Print status based on the variables set after calling initialize_all_clients()
|
392 |
+
print(f" Google Gemini API Configured: {GEMINI_API_READY}")
|
393 |
+
print(f" Hugging Face API Configured: {HF_API_READY}")
|
394 |
+
if not GEMINI_API_READY and not HF_API_READY:
|
395 |
+
print(" CRITICAL WARNING: No API keys seem to be configured correctly. The application will likely be non-functional.")
|
396 |
print(f" UI Default Model Key: {UI_DEFAULT_MODEL_KEY}")
|
397 |
print(f" Available models for UI: {list(AVAILABLE_MODELS_CONFIG.keys())}")
|
398 |
print("="*80)
|
399 |
+
app_demo.launch(debug=True, server_name="0.0.0.0")
|