uzzam2121 commited on
Commit
29ad923
·
1 Parent(s): 9ea8d9d

Add /api/alter OpenAI increase decrease

Browse files
src/deploy/backend/app/main.py CHANGED
@@ -10,6 +10,8 @@ from fastapi.middleware.cors import CORSMiddleware
10
 
11
  from app.config import CORS_ORIGINS, MODEL_PATH
12
  from app.schemas import (
 
 
13
  EfficiencyRequest,
14
  EfficiencyResponse,
15
  HealthResponse,
@@ -133,3 +135,37 @@ def api_intervene_all(body: InterveneAllRequest):
133
  @app.post("/api/efficiency", response_model=EfficiencyResponse)
134
  def api_efficiency(body: EfficiencyRequest):
135
  return compare_efficiency(body.sentence.strip(), body.target_word.strip(), body.local_latency_ms)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
 
11
  from app.config import CORS_ORIGINS, MODEL_PATH
12
  from app.schemas import (
13
+ AlterComplexityRequest,
14
+ AlterComplexityResponse,
15
  EfficiencyRequest,
16
  EfficiencyResponse,
17
  HealthResponse,
 
135
  @app.post("/api/efficiency", response_model=EfficiencyResponse)
136
  def api_efficiency(body: EfficiencyRequest):
137
  return compare_efficiency(body.sentence.strip(), body.target_word.strip(), body.local_latency_ms)
138
+
139
+
140
+ @app.post("/api/alter", response_model=AlterComplexityResponse)
141
+ def api_alter(body: AlterComplexityRequest):
142
+ from reason_interventions import alter_complexity
143
+
144
+ try:
145
+ result = alter_complexity(
146
+ body.reason,
147
+ body.sentence.strip(),
148
+ body.target_word.strip(),
149
+ body.direction,
150
+ )
151
+ except RuntimeError as exc:
152
+ raise HTTPException(status_code=503, detail=str(exc)) from exc
153
+ except ValueError as exc:
154
+ raise HTTPException(status_code=400, detail=str(exc)) from exc
155
+
156
+ if result.reason == "Lexical Rarity":
157
+ updates = "Updated sentence and target word above — click Predict again."
158
+ else:
159
+ updates = "Updated sentence above (target word unchanged) — click Predict again."
160
+
161
+ return AlterComplexityResponse(
162
+ reason=result.reason,
163
+ direction=result.direction,
164
+ original_sentence=result.original_sentence,
165
+ original_target_word=result.original_target,
166
+ new_sentence=result.new_sentence,
167
+ new_target_word=result.new_target,
168
+ edit_method=result.edit_method,
169
+ explanation=result.explanation,
170
+ updates=updates,
171
+ )
src/deploy/backend/app/schemas.py CHANGED
@@ -77,3 +77,22 @@ class HealthResponse(BaseModel):
77
  model_path: str
78
  model_ready: bool
79
  model_error: str | None = None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  model_path: str
78
  model_ready: bool
79
  model_error: str | None = None
80
+
81
+
82
+ class AlterComplexityRequest(BaseModel):
83
+ sentence: str = Field(..., min_length=1)
84
+ target_word: str = Field(..., min_length=1)
85
+ reason: str = Field(..., min_length=1)
86
+ direction: str = Field(..., pattern="^(increase|decrease)$")
87
+
88
+
89
+ class AlterComplexityResponse(BaseModel):
90
+ reason: str
91
+ direction: str
92
+ original_sentence: str
93
+ original_target_word: str
94
+ new_sentence: str
95
+ new_target_word: str
96
+ edit_method: str
97
+ explanation: str
98
+ updates: str
src/reason_interventions.py CHANGED
@@ -130,3 +130,127 @@ def apply_intervention(reason: str, sentence: str, target_word: str, use_llm: bo
130
 
131
  def apply_all_interventions(sentence: str, target_word: str, use_llm: bool = True) -> list[InterventionResult]:
132
  return [fn(sentence, target_word, use_llm=use_llm) for fn in EDIT_FNS.values()]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130
 
131
  def apply_all_interventions(sentence: str, target_word: str, use_llm: bool = True) -> list[InterventionResult]:
132
  return [fn(sentence, target_word, use_llm=use_llm) for fn in EDIT_FNS.values()]
133
+
134
+
135
+ @dataclass
136
+ class AlterComplexityResult:
137
+ reason: str
138
+ direction: str # "increase" | "decrease"
139
+ original_sentence: str
140
+ original_target: str
141
+ new_sentence: str
142
+ new_target: str
143
+ edit_method: str
144
+ explanation: str
145
+
146
+
147
+ def _require_llm(prompt: str) -> tuple[str, str]:
148
+ text, method = _call_llm(prompt)
149
+ if not text or method == "rule":
150
+ raise RuntimeError(
151
+ "OpenAI edit failed. Set OPENAI_API_KEY on the backend (HF Space secrets)."
152
+ )
153
+ return text, method
154
+
155
+
156
+ def _parse_json_block(raw: str) -> dict:
157
+ import json
158
+ import re
159
+
160
+ raw = raw.strip()
161
+ if raw.startswith("```"):
162
+ raw = re.sub(r"^```(?:json)?\s*", "", raw)
163
+ raw = re.sub(r"\s*```$", "", raw)
164
+ return json.loads(raw)
165
+
166
+
167
+ def alter_complexity(
168
+ reason: str,
169
+ sentence: str,
170
+ target_word: str,
171
+ direction: str,
172
+ ) -> AlterComplexityResult:
173
+ """User-guided edit: increase or decrease one complexity dimension via OpenAI."""
174
+ if reason not in EDIT_FNS:
175
+ raise ValueError(f"Unknown reason: {reason}. Choose from {REASON_ORDER}")
176
+ if direction not in ("increase", "decrease"):
177
+ raise ValueError("direction must be 'increase' or 'decrease'")
178
+
179
+ if reason == "Lexical Rarity":
180
+ if direction == "decrease":
181
+ task = (
182
+ f"Replace ONLY '{target_word}' with a MORE COMMON, simpler synonym "
183
+ f"(same meaning and part of speech). Keep the rest of the sentence unchanged."
184
+ )
185
+ else:
186
+ task = (
187
+ f"Replace ONLY '{target_word}' with a RARER, more formal or technical synonym "
188
+ f"(same meaning and part of speech). Keep the rest of the sentence unchanged."
189
+ )
190
+ prompt = (
191
+ f"{task}\n"
192
+ f"Sentence: {sentence}\n"
193
+ f"Target word: {target_word}\n"
194
+ f'Return ONLY valid JSON: {{"sentence": "full sentence with new word", '
195
+ f'"target_word": "the new target word", "explanation": "one short sentence"}}'
196
+ )
197
+ raw, method = _require_llm(prompt)
198
+ data = _parse_json_block(raw)
199
+ new_sentence = str(data["sentence"]).strip()
200
+ new_target = str(data["target_word"]).strip()
201
+ explanation = str(data.get("explanation", "Lexical rarity adjusted."))
202
+ elif reason == "Contextual Ambiguity":
203
+ if direction == "decrease":
204
+ task = (
205
+ f"Rewrite the sentence so the meaning of '{target_word}' is CLEARER and less ambiguous. "
206
+ f"You MUST keep the exact word '{target_word}' unchanged (same spelling)."
207
+ )
208
+ else:
209
+ task = (
210
+ f"Rewrite the sentence so '{target_word}' is MORE AMBIGUOUS in context "
211
+ f"(multiple plausible meanings). You MUST keep the exact word '{target_word}' unchanged."
212
+ )
213
+ prompt = (
214
+ f"{task}\n"
215
+ f"Sentence: {sentence}\n"
216
+ f'Return ONLY valid JSON: {{"sentence": "new sentence", '
217
+ f'"explanation": "one short sentence"}}'
218
+ )
219
+ raw, method = _require_llm(prompt)
220
+ data = _parse_json_block(raw)
221
+ new_sentence = str(data["sentence"]).strip()
222
+ new_target = target_word
223
+ explanation = str(data.get("explanation", "Contextual ambiguity adjusted."))
224
+ else: # Syntactic Complexity
225
+ if direction == "decrease":
226
+ task = (
227
+ f"Simplify the sentence structure to plain, short English. "
228
+ f"You MUST keep the exact word '{target_word}' unchanged."
229
+ )
230
+ else:
231
+ task = (
232
+ f"Make the sentence syntactically MORE COMPLEX (subordinate clauses, passive, etc.). "
233
+ f"You MUST keep the exact word '{target_word}' unchanged."
234
+ )
235
+ prompt = (
236
+ f"{task}\n"
237
+ f"Sentence: {sentence}\n"
238
+ f'Return ONLY valid JSON: {{"sentence": "new sentence", '
239
+ f'"explanation": "one short sentence"}}'
240
+ )
241
+ raw, method = _require_llm(prompt)
242
+ data = _parse_json_block(raw)
243
+ new_sentence = str(data["sentence"]).strip()
244
+ new_target = target_word
245
+ explanation = str(data.get("explanation", "Syntactic complexity adjusted."))
246
+
247
+ return AlterComplexityResult(
248
+ reason=reason,
249
+ direction=direction,
250
+ original_sentence=sentence,
251
+ original_target=target_word,
252
+ new_sentence=new_sentence,
253
+ new_target=new_target,
254
+ edit_method=method,
255
+ explanation=explanation,
256
+ )