suzmen commited on
Commit
55d3bfa
Β·
verified Β·
1 Parent(s): 3ce3d63

Upload 64 files

Browse files
Files changed (1) hide show
  1. app/services/browser.py +37 -26
app/services/browser.py CHANGED
@@ -91,13 +91,19 @@ class BrowserEngine(threading.Thread):
91
  "AppleWebKit/537.36 (KHTML, like Gecko) "
92
  "Chrome/124.0.0.0 Safari/537.36"
93
  ),
94
- viewport={"width": 1920, "height": 1080},
 
 
 
95
  )
96
 
97
- # Hide the webdriver flag
98
- await context.add_init_script(
99
- "Object.defineProperty(navigator, 'webdriver', {get: () => undefined})"
100
- )
 
 
 
101
 
102
  # Inject session token if provided
103
  if settings.CHATGPT_SESSION_TOKEN:
@@ -144,18 +150,22 @@ class BrowserEngine(threading.Thread):
144
  await page.fill("#prompt-textarea", prompt)
145
  await asyncio.sleep(1.0)
146
 
147
- # Robust send: Press Enter AND click the send button
148
  print("[PhantomAPI] πŸ“€ Sending prompt...")
 
149
  await page.press("#prompt-textarea", "Enter")
150
 
151
- # Fallback: Click the send button if Enter didn't trigger it
152
  try:
153
- send_button = await page.wait_for_selector('[data-testid="send-button"]', timeout=3000)
154
- if send_button and await send_button.is_enabled():
155
- await send_button.click()
156
- print("[PhantomAPI] πŸ–±οΈ Clicked Send button.")
 
 
 
157
  except Exception:
158
- pass # Already sent via Enter, or button not found
159
 
160
  # Wait for assistant response OR error message
161
  print("[PhantomAPI] πŸ€– Waiting for response...")
@@ -167,27 +177,25 @@ class BrowserEngine(threading.Thread):
167
  )
168
  print("[PhantomAPI] βœ… Assistant bubble appeared.")
169
 
170
- # Wait for FIRST CHARACTER (Phase 1)
171
  phase1_start = asyncio.get_event_loop().time()
172
  while True:
173
- if asyncio.get_event_loop().time() - phase1_start > 60:
174
  print("[PhantomAPI] ❌ Timeout waiting for first character.")
175
  break
176
 
 
 
 
177
  bubble = await page.query_selector('[data-message-author-role="assistant"]')
178
- content = await (await bubble.query_selector(".markdown, .prose, pre") or bubble).inner_text()
 
179
 
180
  if content.strip():
181
- print("[PhantomAPI] πŸ“’ Detected typing start...")
182
  break
183
 
184
- # Log if it's still busy but empty
185
- busy = await bubble.get_attribute("aria-busy")
186
- if busy == "true":
187
- # Still generating, just wait
188
- pass
189
-
190
- await asyncio.sleep(1.0)
191
 
192
  except Exception as e:
193
  # Diagnostics: What is actually on the page?
@@ -218,6 +226,9 @@ class BrowserEngine(threading.Thread):
218
  print("[PhantomAPI] ⚠️ Hard timeout reached.")
219
  break
220
 
 
 
 
221
  bubble = await page.query_selector('[data-message-author-role="assistant"]')
222
  if not bubble: break
223
 
@@ -238,11 +249,11 @@ class BrowserEngine(threading.Thread):
238
  if is_busy != "true":
239
  unchanged_count += 1
240
 
241
- if unchanged_count >= 4:
242
- print("[PhantomAPI] βœ… Generation finished (stability reached).")
243
  break
244
 
245
- await asyncio.sleep(0.5)
246
 
247
  await self._save_debug_screenshot(page)
248
  print(f"[PhantomAPI] ✨ Response complete ({len(last_text)} chars).")
 
91
  "AppleWebKit/537.36 (KHTML, like Gecko) "
92
  "Chrome/124.0.0.0 Safari/537.36"
93
  ),
94
+ viewport={"width": 1280, "height": 800},
95
+ device_scale_factor=1,
96
+ has_touch=False,
97
+ is_mobile=False,
98
  )
99
 
100
+ # Advanced Stealth Overrides
101
+ await context.add_init_script("""
102
+ Object.defineProperty(navigator, 'webdriver', {get: () => undefined});
103
+ Object.defineProperty(navigator, 'languages', {get: () => ['en-US', 'en']});
104
+ Object.defineProperty(navigator, 'platform', {get: () => 'Win32'});
105
+ Object.defineProperty(navigator, 'vendor', {get: () => 'Google Inc.'});
106
+ """)
107
 
108
  # Inject session token if provided
109
  if settings.CHATGPT_SESSION_TOKEN:
 
150
  await page.fill("#prompt-textarea", prompt)
151
  await asyncio.sleep(1.0)
152
 
153
+ # Robust send: Press Enter AND mouse-click the send button
154
  print("[PhantomAPI] πŸ“€ Sending prompt...")
155
+ await asyncio.sleep(random.uniform(0.5, 1.5))
156
  await page.press("#prompt-textarea", "Enter")
157
 
158
+ # Fallback: Real mouse click on the send button
159
  try:
160
+ btn = await page.wait_for_selector('[data-testid="send-button"]', timeout=3000)
161
+ if btn and await btn.is_enabled():
162
+ # Get button coordinates and click with mouse
163
+ box = await btn.bounding_box()
164
+ if box:
165
+ await page.mouse.click(box['x'] + box['width']/2, box['y'] + box['height']/2)
166
+ print("[PhantomAPI] πŸ–±οΈ Mouse-clicked Send button.")
167
  except Exception:
168
+ pass
169
 
170
  # Wait for assistant response OR error message
171
  print("[PhantomAPI] πŸ€– Waiting for response...")
 
177
  )
178
  print("[PhantomAPI] βœ… Assistant bubble appeared.")
179
 
180
+ # Phase 1: Wait for text to appear (Up to 90s)
181
  phase1_start = asyncio.get_event_loop().time()
182
  while True:
183
+ if asyncio.get_event_loop().time() - phase1_start > 90:
184
  print("[PhantomAPI] ❌ Timeout waiting for first character.")
185
  break
186
 
187
+ # Scroll to bottom to trigger rendering
188
+ await page.evaluate("window.scrollTo(0, document.body.scrollHeight)")
189
+
190
  bubble = await page.query_selector('[data-message-author-role="assistant"]')
191
+ target = await bubble.query_selector(".markdown, .prose, pre") or bubble
192
+ content = await target.inner_text()
193
 
194
  if content.strip():
195
+ print(f"[PhantomAPI] πŸ“’ Detected typing start! ({len(content)} chars)")
196
  break
197
 
198
+ await asyncio.sleep(2.0)
 
 
 
 
 
 
199
 
200
  except Exception as e:
201
  # Diagnostics: What is actually on the page?
 
226
  print("[PhantomAPI] ⚠️ Hard timeout reached.")
227
  break
228
 
229
+ # Scroll to bottom regularly
230
+ await page.evaluate("window.scrollTo(0, document.body.scrollHeight)")
231
+
232
  bubble = await page.query_selector('[data-message-author-role="assistant"]')
233
  if not bubble: break
234
 
 
249
  if is_busy != "true":
250
  unchanged_count += 1
251
 
252
+ if unchanged_count >= 5: # Slightly longer stability check
253
+ print("[PhantomAPI] βœ… Generation finished.")
254
  break
255
 
256
+ await asyncio.sleep(1.0)
257
 
258
  await self._save_debug_screenshot(page)
259
  print(f"[PhantomAPI] ✨ Response complete ({len(last_text)} chars).")