Spaces:
Sleeping
Sleeping
various changes
Browse files- .gitignore +2 -0
- app.py +58 -33
.gitignore
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
|
|
|
| 1 |
+
__pycache__
|
| 2 |
+
|
app.py
CHANGED
|
@@ -27,7 +27,7 @@ client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
|
|
| 27 |
override_header = os.getenv("OVERRIDE_HEADER")
|
| 28 |
login_password = os.getenv("LOGIN_PASSWORD")
|
| 29 |
|
| 30 |
-
def compare_cameras(model_name: str, prompt: str, camera1_specs: CameraSpecs, camera2_specs: CameraSpecs) -> SimpleComparisonSummary:
|
| 31 |
"""
|
| 32 |
Compares two product specifications using OpenAI and returns a structured summary.
|
| 33 |
"""
|
|
@@ -43,20 +43,43 @@ def compare_cameras(model_name: str, prompt: str, camera1_specs: CameraSpecs, ca
|
|
| 43 |
{camera2_specs.model_dump_json(indent=2)}
|
| 44 |
"""
|
| 45 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 46 |
try:
|
| 47 |
-
response = client.
|
| 48 |
-
model=
|
| 49 |
-
|
| 50 |
-
{"role": "system", "content": "You are a helpful assistant that compares camera specifications and outputs JSON."},
|
| 51 |
-
{"role": "user", "content": prompt}
|
| 52 |
],
|
| 53 |
-
|
| 54 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 55 |
)
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 60 |
return SimpleComparisonSummary(**summary_data)
|
| 61 |
except Exception as e:
|
| 62 |
print(f"An error occurred: {e}")
|
|
@@ -106,9 +129,8 @@ def extract_group_details(data):
|
|
| 106 |
return extracted_data
|
| 107 |
|
| 108 |
|
| 109 |
-
model_list = ["gpt-
|
| 110 |
-
default_prompt = """
|
| 111 |
-
Follow this exact markdown heading arrangement in your response:
|
| 112 |
|
| 113 |
### Which Is Right for You?
|
| 114 |
Provide two clear, persuasive paragraphs—one advocating for product A and the other for product B—each tailored to a distinct use case or preference based on the given specs.
|
|
@@ -121,10 +143,9 @@ List and explain the most significant shared features of the products. This sect
|
|
| 121 |
|
| 122 |
If any specification for either product is missing or unavailable, note this clearly at the appropriate place in your summary (e.g., '[Product Name] specification not provided'). Do not mention pricing.
|
| 123 |
|
| 124 |
-
Maintain the prescribed section order: Which Is Right for You, Main Differences, and Key Similarities. Ensure every section is included, even if you must state that information is missing.
|
| 125 |
-
"""
|
| 126 |
|
| 127 |
-
def compare_cameras_gui(model_name, prompt, sku1, sku2):
|
| 128 |
"""
|
| 129 |
Gradio interface function to compare cameras based on SKU numbers and model name.
|
| 130 |
"""
|
|
@@ -138,7 +159,7 @@ def compare_cameras_gui(model_name, prompt, sku1, sku2):
|
|
| 138 |
camera_b = CameraSpecs(model=specs_b['model'], specs=specs_b['specs'])
|
| 139 |
names = [specs_a['model'], specs_b['model']]
|
| 140 |
|
| 141 |
-
summary = compare_cameras(model_name, prompt, camera_a, camera_b)
|
| 142 |
|
| 143 |
if summary:
|
| 144 |
# Format the output for display in Gradio using more standard markdown syntax
|
|
@@ -152,29 +173,33 @@ def compare_cameras_gui(model_name, prompt, sku1, sku2):
|
|
| 152 |
|
| 153 |
|
| 154 |
default_response_filler="""
|
| 155 |
-
|
| 156 |
## Output will display here,
|
| 157 |
|
| 158 |
### Add 2 sku numbers to compare.
|
| 159 |
|
| 160 |
There is some delay before loading the output, please be patient.
|
| 161 |
"""
|
| 162 |
-
|
| 163 |
-
|
| 164 |
-
|
| 165 |
-
|
| 166 |
-
|
| 167 |
-
|
| 168 |
-
|
| 169 |
-
|
| 170 |
-
|
| 171 |
-
|
| 172 |
-
|
| 173 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 174 |
|
| 175 |
def authenticate(username, password):
|
| 176 |
return username == "bnh" and password == login_password
|
| 177 |
|
| 178 |
# Launch the interface
|
| 179 |
# Disable Gradio's experimental SSR to avoid svelte-i18n initial locale errors in server-side rendering
|
| 180 |
-
|
|
|
|
| 27 |
override_header = os.getenv("OVERRIDE_HEADER")
|
| 28 |
login_password = os.getenv("LOGIN_PASSWORD")
|
| 29 |
|
| 30 |
+
def compare_cameras(model_name: str, prompt: str, camera1_specs: CameraSpecs, camera2_specs: CameraSpecs, verbosity: str = "Low", reasoning_level: str = "Minimal") -> SimpleComparisonSummary:
|
| 31 |
"""
|
| 32 |
Compares two product specifications using OpenAI and returns a structured summary.
|
| 33 |
"""
|
|
|
|
| 43 |
{camera2_specs.model_dump_json(indent=2)}
|
| 44 |
"""
|
| 45 |
|
| 46 |
+
# Map verbosity and reasoning level to Responses API parameters
|
| 47 |
+
verbosity_map = {
|
| 48 |
+
"Low": (600, "Keep the response concise and focused on essentials."),
|
| 49 |
+
"Medium": (1200, "Provide a balanced level of detail."),
|
| 50 |
+
"High": (2000, "Be thorough and include more detail and nuance."),
|
| 51 |
+
}
|
| 52 |
+
max_tokens, verbosity_hint = verbosity_map.get(verbosity, (600, "Keep the response concise."))
|
| 53 |
+
|
| 54 |
+
reasoning_map = {"Minimal": "low", "Medium": "medium", "High": "high"}
|
| 55 |
+
reasoning_effort = reasoning_map.get(reasoning_level, "low")
|
| 56 |
+
|
| 57 |
try:
|
| 58 |
+
response = client.responses.create(
|
| 59 |
+
model=model_name,
|
| 60 |
+
input=[
|
| 61 |
+
{"role": "system", "content": [{"type": "text", "text": "You are a helpful assistant that compares camera specifications and outputs JSON. " + verbosity_hint}]},
|
| 62 |
+
{"role": "user", "content": [{"type": "text", "text": prompt}]},
|
| 63 |
],
|
| 64 |
+
response_format={
|
| 65 |
+
"type": "json_schema",
|
| 66 |
+
"json_schema": {
|
| 67 |
+
"name": "SimpleComparisonSummary",
|
| 68 |
+
"schema": SimpleComparisonSummary.model_json_schema(),
|
| 69 |
+
"strict": True,
|
| 70 |
+
},
|
| 71 |
+
},
|
| 72 |
+
max_output_tokens=max_tokens,
|
| 73 |
+
reasoning={"effort": reasoning_effort},
|
| 74 |
)
|
| 75 |
+
|
| 76 |
+
try:
|
| 77 |
+
json_text = response.output_text # type: ignore
|
| 78 |
+
except Exception:
|
| 79 |
+
# Fallback to explicit path
|
| 80 |
+
json_text = response.output[0].content[0].text # type: ignore
|
| 81 |
+
|
| 82 |
+
summary_data = json.loads(json_text)
|
| 83 |
return SimpleComparisonSummary(**summary_data)
|
| 84 |
except Exception as e:
|
| 85 |
print(f"An error occurred: {e}")
|
|
|
|
| 129 |
return extracted_data
|
| 130 |
|
| 131 |
|
| 132 |
+
model_list = ["gpt-5-nano", "gpt-5-mini", "gpt-5"]
|
| 133 |
+
default_prompt = """Follow this exact markdown heading arrangement in your response:
|
|
|
|
| 134 |
|
| 135 |
### Which Is Right for You?
|
| 136 |
Provide two clear, persuasive paragraphs—one advocating for product A and the other for product B—each tailored to a distinct use case or preference based on the given specs.
|
|
|
|
| 143 |
|
| 144 |
If any specification for either product is missing or unavailable, note this clearly at the appropriate place in your summary (e.g., '[Product Name] specification not provided'). Do not mention pricing.
|
| 145 |
|
| 146 |
+
Maintain the prescribed section order: Which Is Right for You, Main Differences, and Key Similarities. Ensure every section is included, even if you must state that information is missing."""
|
|
|
|
| 147 |
|
| 148 |
+
def compare_cameras_gui(model_name, verbosity, reasoning_level, prompt, sku1, sku2):
|
| 149 |
"""
|
| 150 |
Gradio interface function to compare cameras based on SKU numbers and model name.
|
| 151 |
"""
|
|
|
|
| 159 |
camera_b = CameraSpecs(model=specs_b['model'], specs=specs_b['specs'])
|
| 160 |
names = [specs_a['model'], specs_b['model']]
|
| 161 |
|
| 162 |
+
summary = compare_cameras(model_name, prompt, camera_a, camera_b, verbosity=verbosity, reasoning_level=reasoning_level)
|
| 163 |
|
| 164 |
if summary:
|
| 165 |
# Format the output for display in Gradio using more standard markdown syntax
|
|
|
|
| 173 |
|
| 174 |
|
| 175 |
default_response_filler="""
|
|
|
|
| 176 |
## Output will display here,
|
| 177 |
|
| 178 |
### Add 2 sku numbers to compare.
|
| 179 |
|
| 180 |
There is some delay before loading the output, please be patient.
|
| 181 |
"""
|
| 182 |
+
with gr.Blocks(title="Product Comparison Tool") as demo:
|
| 183 |
+
gr.Markdown("Enter two B&H Photo SKU numbers to compare two products.")
|
| 184 |
+
with gr.Row():
|
| 185 |
+
model_dd = gr.Dropdown(choices=model_list, label="Select OpenAI Model", value="gpt-5-nano")
|
| 186 |
+
verbosity_dd = gr.Dropdown(choices=["Low", "Medium", "High"], label="Verbosity", value="Low")
|
| 187 |
+
reasoning_dd = gr.Dropdown(choices=["Minimal", "Low", "Medium", "High"], label="Reasoning Level", value="Minimal")
|
| 188 |
+
prompt_tb = gr.Textbox(label="System Prompt", value=default_prompt)
|
| 189 |
+
sku1_tb = gr.Textbox(label="Enter SKU for Product 1")
|
| 190 |
+
sku2_tb = gr.Textbox(label="Enter SKU for Product 2")
|
| 191 |
+
output_md = gr.Markdown(label="Comparison Result", value=default_response_filler)
|
| 192 |
+
submit_btn = gr.Button("Compare")
|
| 193 |
+
|
| 194 |
+
submit_btn.click(
|
| 195 |
+
fn=compare_cameras_gui,
|
| 196 |
+
inputs=[model_dd, verbosity_dd, reasoning_dd, prompt_tb, sku1_tb, sku2_tb],
|
| 197 |
+
outputs=output_md,
|
| 198 |
+
)
|
| 199 |
|
| 200 |
def authenticate(username, password):
|
| 201 |
return username == "bnh" and password == login_password
|
| 202 |
|
| 203 |
# Launch the interface
|
| 204 |
# Disable Gradio's experimental SSR to avoid svelte-i18n initial locale errors in server-side rendering
|
| 205 |
+
demo.launch(auth=authenticate, share=False, ssr_mode=False)
|