ajit3259 commited on
Commit
d0aa261
·
1 Parent(s): 593e278

fix(backend): first pass respects refined env flag; add A/B override

Browse files

The first pass was hardcoded to baseline, so CHALCHITRA_REFINED_PROMPT was
ignored except on retry. Now the first pass uses the configured default
(refined=None reads the env). Adds an optional per-request `refined` override
(API + interpret) for a single clean pass — used to A/B baseline vs refined on
the same image against the live model. The frontend never sends it.

Files changed (2) hide show
  1. app.py +6 -1
  2. backend/oracle.py +12 -5
app.py CHANGED
@@ -106,6 +106,7 @@ class Moment(BaseModel):
106
  images: list[str] = Field(default_factory=list) # data URLs or raw base64 JPEG
107
  fragment: str = ""
108
  exclude: list[str] = Field(default_factory=list) # titles already shown this session
 
109
 
110
 
111
  @app.post("/api/interpret")
@@ -114,7 +115,11 @@ async def api_interpret(moment: Moment):
114
  return JSONResponse({"error": "Bring at least one image."}, status_code=400)
115
  try:
116
  return interpret(
117
- moment.images, moment.fragment, provider=_provider(), exclude=moment.exclude
 
 
 
 
118
  )
119
  except InputError as exc:
120
  # Bad/oversized/unsupported input — rejected before reaching the model.
 
106
  images: list[str] = Field(default_factory=list) # data URLs or raw base64 JPEG
107
  fragment: str = ""
108
  exclude: list[str] = Field(default_factory=list) # titles already shown this session
109
+ refined: bool | None = None # optional A/B override of the prompt variant
110
 
111
 
112
  @app.post("/api/interpret")
 
115
  return JSONResponse({"error": "Bring at least one image."}, status_code=400)
116
  try:
117
  return interpret(
118
+ moment.images,
119
+ moment.fragment,
120
+ provider=_provider(),
121
+ exclude=moment.exclude,
122
+ refined=moment.refined,
123
  )
124
  except InputError as exc:
125
  # Bad/oversized/unsupported input — rejected before reaching the model.
backend/oracle.py CHANGED
@@ -148,6 +148,7 @@ def interpret(
148
  fragment: str = "",
149
  provider: Provider | None = None,
150
  exclude: list[str] | None = None,
 
151
  ) -> dict[str, Any]:
152
  """Run the full flow. `images` are data URLs or raw base64 JPEG strings.
153
 
@@ -155,9 +156,10 @@ def interpret(
155
  different films that still fit the moment (the "other films" re-roll).
156
  Stateless — that list lives on the client and rides in the request.
157
 
158
- If the first interpretation reads flat or breaks the "never describe the
159
- photo" rule, retry once with the refined prompt and a hotter temperature,
160
- then keep whichever pass is stronger.
 
161
  """
162
  # Guardrails first: decode/validate/re-encode images and clean the inputs
163
  # before anything reaches the model. InputError propagates to a clean 4xx.
@@ -168,10 +170,15 @@ def interpret(
168
  provider = provider or get_provider()
169
  content = _build_content(images, fragment, exclude)
170
 
171
- # First pass with the configured prompt. If it parses and reads well, ship it.
 
 
 
 
 
172
  first: dict[str, Any] | None = None
173
  try:
174
- first = _run(provider, content, refined=False)
175
  if not _is_weak(first["interpretation"]):
176
  return first
177
  except OracleError:
 
148
  fragment: str = "",
149
  provider: Provider | None = None,
150
  exclude: list[str] | None = None,
151
+ refined: bool | None = None,
152
  ) -> dict[str, Any]:
153
  """Run the full flow. `images` are data URLs or raw base64 JPEG strings.
154
 
 
156
  different films that still fit the moment (the "other films" re-roll).
157
  Stateless — that list lives on the client and rides in the request.
158
 
159
+ `refined` overrides the prompt variant for a single clean pass (no retry) —
160
+ used for A/B testing the baseline vs refined prompt on the same image. When
161
+ None (the normal path), the first pass uses the configured default and one
162
+ retry with the refined prompt covers a flat or unparseable reply.
163
  """
164
  # Guardrails first: decode/validate/re-encode images and clean the inputs
165
  # before anything reaches the model. InputError propagates to a clean 4xx.
 
170
  provider = provider or get_provider()
171
  content = _build_content(images, fragment, exclude)
172
 
173
+ # Explicit override (A/B / debugging): one clean pass with the chosen variant.
174
+ if refined is not None:
175
+ return _run(provider, content, refined=refined)
176
+
177
+ # First pass with the configured default (refined=None reads the env flag).
178
+ # If it parses and reads well, ship it.
179
  first: dict[str, Any] | None = None
180
  try:
181
+ first = _run(provider, content, refined=None)
182
  if not _is_weak(first["interpretation"]):
183
  return first
184
  except OracleError: