SreekarB commited on
Commit
75d8ea0
·
verified ·
1 Parent(s): f349331

Update annotated_casl_app.py

Browse files
Files changed (1) hide show
  1. annotated_casl_app.py +8 -247
annotated_casl_app.py CHANGED
@@ -96,174 +96,6 @@ def combine_sections_smartly(sections_dict):
96
 
97
  return '\n'.join(combined_parts)
98
 
99
- def call_claude_api_with_continuation(prompt, max_continuations=0):
100
- """Call Claude API with smart continuation system - unlimited continuations until complete"""
101
- if not ANTHROPIC_API_KEY:
102
- return "❌ Claude API key not configured. Please set ANTHROPIC_API_KEY environment variable."
103
-
104
- # Define all required sections
105
- required_sections = [
106
- "1. SPEECH FACTORS",
107
- "2. LANGUAGE SKILLS ASSESSMENT",
108
- "3. COMPLEX SENTENCE ANALYSIS",
109
- "4. FIGURATIVE LANGUAGE ANALYSIS",
110
- "5. PRAGMATIC LANGUAGE ASSESSMENT",
111
- "6. VOCABULARY AND SEMANTIC ANALYSIS",
112
- "7. MORPHOLOGICAL AND PHONOLOGICAL ANALYSIS",
113
- "8. COGNITIVE-LINGUISTIC FACTORS",
114
- "9. FLUENCY AND RHYTHM ANALYSIS",
115
- "10. QUANTITATIVE METRICS",
116
- "11. CLINICAL IMPLICATIONS",
117
- "12. PROGNOSIS AND SUMMARY"
118
- ]
119
-
120
- # Safety limits to prevent infinite loops
121
- MAX_CONTINUATIONS = 30 # Increased from 20 to 30 API calls
122
- MAX_TIME_MINUTES = 15 # Increased from 10 to 15 minutes total
123
- MIN_PROGRESS_PER_CALL = 0 # Changed from 1 to 0 to allow more flexibility
124
-
125
- try:
126
- all_sections = {} # Store all sections found across all parts
127
- continuation_count = 0
128
- start_time = time.time()
129
- last_section_count = 0 # Track progress between calls
130
-
131
- # Add continuation instruction to original prompt
132
- initial_prompt = prompt + "\n\nCRITICAL INSTRUCTIONS: You MUST complete ALL 12 sections of the analysis. If your response is cut off or incomplete, end with <CONTINUE> to indicate more content is needed. Do not skip any sections. Use the checklist to ensure all sections are completed."
133
-
134
- while True: # Unlimited continuations until complete
135
- if continuation_count == 0:
136
- current_prompt = initial_prompt
137
- else:
138
- # For continuations, provide context about what was already covered
139
- missing_sections = [s for s in required_sections if s not in all_sections]
140
- missing_text = "\n".join([f"- {section}" for section in missing_sections])
141
-
142
- current_prompt = prompt + f"\n\nCONTINUATION {continuation_count + 1}: The following sections are STILL MISSING and MUST be completed:\n\n{missing_text}\n\nCRITICAL: Provide ONLY these missing sections. Do not repeat any sections that are already complete. Focus exclusively on the missing sections listed above. Complete ALL missing sections in this response."
143
-
144
- headers = {
145
- "Content-Type": "application/json",
146
- "x-api-key": ANTHROPIC_API_KEY,
147
- "anthropic-version": "2023-06-01"
148
- }
149
-
150
- data = {
151
- "model": "claude-sonnet-4-5",
152
- "max_tokens": 4096,
153
- "messages": [
154
- {
155
- "role": "user",
156
- "content": current_prompt
157
- }
158
- ]
159
- }
160
-
161
- response = requests.post(
162
- "https://api.anthropic.com/v1/messages",
163
- headers=headers,
164
- json=data,
165
- timeout=90
166
- )
167
-
168
- if response.status_code == 200:
169
- response_json = response.json()
170
- response_text = response_json['content'][0]['text']
171
-
172
- # Log response for debugging
173
- print(f"\n=== PART {continuation_count + 1} RESPONSE ===")
174
- print(f"Length: {len(response_text)} characters")
175
- print(f"Contains CONTINUE: {'<CONTINUE>' in response_text}")
176
- print(f"First 200 chars: {response_text[:200]}...")
177
- print(f"Last 200 chars: {response_text[-200:]}...")
178
- print("=" * 50)
179
-
180
- # Segment this part and add new sections to our collection
181
- part_sections = segment_response_by_sections(response_text)
182
- for section, content in part_sections.items():
183
- if section not in all_sections: # Only add if not already present
184
- all_sections[section] = content
185
- print(f"Added section: {section}")
186
- else:
187
- print(f"Skipped duplicate section: {section}")
188
-
189
- # Check completion status
190
- completed_sections = len(all_sections)
191
- missing_sections = [s for s in required_sections if s not in all_sections]
192
-
193
- print(f"Completed sections: {completed_sections}/12")
194
- print(f"Missing sections: {missing_sections}")
195
-
196
- # Check if response indicates continuation is needed
197
- needs_continuation = "<CONTINUE>" in response_text
198
-
199
- print(f"Needs continuation: {needs_continuation}")
200
- print(f"Continuation count: {continuation_count}")
201
-
202
- # Safety checks to prevent infinite loops
203
- current_time = time.time()
204
- elapsed_minutes = (current_time - start_time) / 60
205
- current_section_count = len(all_sections)
206
- progress_made = current_section_count - last_section_count
207
-
208
- # Check if we're making progress
209
- if continuation_count > 0 and progress_made < MIN_PROGRESS_PER_CALL:
210
- # Only stop if we've made multiple calls with no progress
211
- if continuation_count > 3: # Allow more attempts before giving up
212
- logger.warning(f"No progress made in last call (added {progress_made} sections). Stopping to prevent infinite loop.")
213
- break
214
- else:
215
- logger.info(f"No progress in call {continuation_count}, but continuing to allow more attempts...")
216
-
217
- # Check time limit
218
- if elapsed_minutes > MAX_TIME_MINUTES:
219
- logger.warning(f"Time limit exceeded ({elapsed_minutes:.1f} minutes). Stopping to prevent excessive API usage.")
220
- break
221
-
222
- # Check continuation limit
223
- if continuation_count >= MAX_CONTINUATIONS:
224
- logger.warning(f"Continuation limit reached ({MAX_CONTINUATIONS} calls). Stopping to prevent excessive API usage.")
225
- break
226
-
227
- # Continue if <CONTINUE> is present and safety checks pass
228
- if needs_continuation:
229
- continuation_count += 1
230
- last_section_count = current_section_count
231
- logger.info(f"Continuing analysis (attempt {continuation_count}/{MAX_CONTINUATIONS}, {elapsed_minutes:.1f} minutes elapsed)")
232
- continue
233
- else:
234
- break
235
- else:
236
- logger.error(f"Claude API error: {response.status_code} - {response.text}")
237
- return f"❌ Claude API Error: {response.status_code}"
238
-
239
- except Exception as e:
240
- logger.error(f"Error calling Claude API: {str(e)}")
241
- return f"❌ Error: {str(e)}"
242
-
243
- # Combine all sections in the correct order
244
- final_response = combine_sections_smartly(all_sections)
245
-
246
- # Log final results
247
- print(f"\n=== FINAL SMART VALIDATION ===")
248
- print(f"Total sections found: {len(all_sections)}")
249
- print(f"All sections present: {len(all_sections) == 12}")
250
- print(f"Missing sections: {[s for s in required_sections if s not in all_sections]}")
251
- print(f"Total time: {(time.time() - start_time) / 60:.1f} minutes")
252
- print(f"Total API calls: {continuation_count + 1}")
253
- print("=" * 50)
254
-
255
- # Add completion indicator with safety info
256
- if continuation_count > 0:
257
- final_response += f"\n\n[Analysis completed in {continuation_count + 1} parts over {(time.time() - start_time) / 60:.1f} minutes]"
258
-
259
- # Add warning if incomplete due to safety limits
260
- if len(all_sections) < 12:
261
- missing_sections = [s for s in required_sections if s not in all_sections]
262
- final_response += f"\n\n⚠️ WARNING: Analysis incomplete due to safety limits. Missing sections: {', '.join(missing_sections)}"
263
- final_response += f"\n\n💡 TIP: Try running the analysis again, or use the 'Targeted Analysis' tab to focus on specific areas."
264
- final_response += f"\nThe 'Quick Questions' tab may also provide faster results for specific areas of interest."
265
-
266
- return final_response
267
 
268
  def call_claude_api_quick_analysis(prompt):
269
  """Call Claude API for quick focused analysis - single response only"""
@@ -1453,84 +1285,6 @@ def process_file(file):
1453
  except Exception as e:
1454
  return f"Error reading file: {str(e)}"
1455
 
1456
- def segment_response_by_sections(response_text):
1457
- """Segment response by section titles and return a dictionary of sections"""
1458
- required_sections = [
1459
- "1. SPEECH FACTORS",
1460
- "2. LANGUAGE SKILLS ASSESSMENT",
1461
- "3. COMPLEX SENTENCE ANALYSIS",
1462
- "4. FIGURATIVE LANGUAGE ANALYSIS",
1463
- "5. PRAGMATIC LANGUAGE ASSESSMENT",
1464
- "6. VOCABULARY AND SEMANTIC ANALYSIS",
1465
- "7. MORPHOLOGICAL AND PHONOLOGICAL ANALYSIS",
1466
- "8. COGNITIVE-LINGUISTIC FACTORS",
1467
- "9. FLUENCY AND RHYTHM ANALYSIS",
1468
- "10. QUANTITATIVE METRICS",
1469
- "11. CLINICAL IMPLICATIONS",
1470
- "12. PROGNOSIS AND SUMMARY"
1471
- ]
1472
-
1473
- sections = {}
1474
- current_section = None
1475
- current_content = []
1476
-
1477
- lines = response_text.split('\n')
1478
-
1479
- for line in lines:
1480
- # Check if this line is a section header
1481
- is_section_header = False
1482
- for section in required_sections:
1483
- if section in line:
1484
- # Save previous section if exists
1485
- if current_section and current_content:
1486
- sections[current_section] = '\n'.join(current_content).strip()
1487
-
1488
- # Start new section
1489
- current_section = section
1490
- current_content = []
1491
- is_section_header = True
1492
- break
1493
-
1494
- # If not a section header, add to current section content
1495
- if not is_section_header and current_section:
1496
- current_content.append(line)
1497
-
1498
- # Save the last section
1499
- if current_section and current_content:
1500
- sections[current_section] = '\n'.join(current_content).strip()
1501
-
1502
- return sections
1503
-
1504
- def combine_sections_smartly(sections_dict):
1505
- """Combine sections in the correct order without duplicates"""
1506
- required_sections = [
1507
- "1. SPEECH FACTORS",
1508
- "2. LANGUAGE SKILLS ASSESSMENT",
1509
- "3. COMPLEX SENTENCE ANALYSIS",
1510
- "4. FIGURATIVE LANGUAGE ANALYSIS",
1511
- "5. PRAGMATIC LANGUAGE ASSESSMENT",
1512
- "6. VOCABULARY AND SEMANTIC ANALYSIS",
1513
- "7. MORPHOLOGICAL AND PHONOLOGICAL ANALYSIS",
1514
- "8. COGNITIVE-LINGUISTIC FACTORS",
1515
- "9. FLUENCY AND RHYTHM ANALYSIS",
1516
- "10. QUANTITATIVE METRICS",
1517
- "11. CLINICAL IMPLICATIONS",
1518
- "12. PROGNOSIS AND SUMMARY"
1519
- ]
1520
-
1521
- combined_parts = []
1522
- combined_parts.append("COMPREHENSIVE SPEECH SAMPLE ANALYSIS")
1523
- combined_parts.append("")
1524
-
1525
- for section in required_sections:
1526
- if section in sections_dict:
1527
- combined_parts.append(section)
1528
- combined_parts.append("")
1529
- combined_parts.append(sections_dict[section])
1530
- combined_parts.append("")
1531
-
1532
- return '\n'.join(combined_parts)
1533
-
1534
  def call_claude_api_with_continuation(prompt):
1535
  """Call Claude API with smart continuation system - unlimited continuations until complete"""
1536
  if not ANTHROPIC_API_KEY:
@@ -1629,8 +1383,15 @@ def call_claude_api_with_continuation(prompt):
1629
  print(f"Missing sections: {missing_sections}")
1630
 
1631
  # Check if response indicates continuation is needed
1632
- needs_continuation = "<CONTINUE>" in response_text
 
 
 
 
1633
 
 
 
 
1634
  print(f"Needs continuation: {needs_continuation}")
1635
  print(f"Continuation count: {continuation_count}")
1636
 
 
96
 
97
  return '\n'.join(combined_parts)
98
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
99
 
100
  def call_claude_api_quick_analysis(prompt):
101
  """Call Claude API for quick focused analysis - single response only"""
 
1285
  except Exception as e:
1286
  return f"Error reading file: {str(e)}"
1287
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1288
  def call_claude_api_with_continuation(prompt):
1289
  """Call Claude API with smart continuation system - unlimited continuations until complete"""
1290
  if not ANTHROPIC_API_KEY:
 
1383
  print(f"Missing sections: {missing_sections}")
1384
 
1385
  # Check if response indicates continuation is needed
1386
+ has_continue_marker = "<CONTINUE>" in response_text
1387
+ has_missing_sections = len(missing_sections) > 0
1388
+
1389
+ # Continuation needed if either marker present OR sections missing
1390
+ needs_continuation = has_continue_marker or has_missing_sections
1391
 
1392
+ print(f"Has <CONTINUE> marker: {has_continue_marker}")
1393
+ print(f"Has missing sections: {has_missing_sections}")
1394
+ print(f"Missing sections: {missing_sections}")
1395
  print(f"Needs continuation: {needs_continuation}")
1396
  print(f"Continuation count: {continuation_count}")
1397