akashyadav758 Claude Opus 4.8 (1M context) commited on
Commit
1618d7c
·
1 Parent(s): 9d8e1f7

Fix dropped full_conversation replies: don't early-return on rawText

Browse files

The extension's full_conversation reply always carries `rawText` in its
result. handleExtensionMessage returned early when RawSSEOutputPath was
unset, so the reply never reached pending[msg.ID] and every browser-mode
chat timed out (240s) with an empty response. Now the raw-SSE dump is
purely optional and dispatch always continues to the pending channel.

Also sync the validated gpt-extension/background.js into the Docker build
source so HF builds the working extension.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

chatgpt-free-api/extension.go CHANGED
@@ -88,12 +88,14 @@ func handleExtensionMessage(msg WSMessage) {
88
  if msg.Result != nil {
89
  if m, ok := msg.Result.(map[string]any); ok {
90
  if raw, ok := m["rawText"].(string); ok {
91
- if cfg.RawSSEOutputPath == "" {
92
- return
93
- }
94
- err := os.WriteFile(cfg.RawSSEOutputPath, []byte(raw), 0644)
95
- if err != nil {
96
- log.Printf("ERROR WRITING RAW SSE: %v", err)
 
 
97
  }
98
  }
99
  }
 
88
  if msg.Result != nil {
89
  if m, ok := msg.Result.(map[string]any); ok {
90
  if raw, ok := m["rawText"].(string); ok {
91
+ // Optionally dump the raw SSE for debugging. This must NOT
92
+ // short-circuit dispatch: the same reply still has to reach the
93
+ // pending[msg.ID] channel below, otherwise full_conversation
94
+ // responses are silently dropped and the caller times out.
95
+ if cfg.RawSSEOutputPath != "" {
96
+ if err := os.WriteFile(cfg.RawSSEOutputPath, []byte(raw), 0644); err != nil {
97
+ log.Printf("ERROR WRITING RAW SSE: %v", err)
98
+ }
99
  }
100
  }
101
  }
chatgpt-free-api/gpt-extension/background.js CHANGED
@@ -900,7 +900,31 @@ async function handleFullConversation(msg) {
900
  return;
901
  }
902
 
903
- const text = await convResp.text();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
904
  let convId = '';
905
  const parseSSEFinal = (raw) => {
906
  let snapshot = '';
 
900
  return;
901
  }
902
 
903
+ // Read the SSE stream incrementally instead of await convResp.text().
904
+ // ChatGPT keeps the HTTP connection alive after emitting `data: [DONE]`, so
905
+ // .text() (which resolves only on connection close) hangs forever. We stop as
906
+ // soon as we see the stream-completion marker, with a hard safety deadline.
907
+ let text = '';
908
+ {
909
+ const STREAM_DEADLINE_MS = 180000; // overall cap so a stalled stream can't hang the SW
910
+ const deadline = Date.now() + STREAM_DEADLINE_MS;
911
+ try {
912
+ const reader = convResp.body.getReader();
913
+ const decoder = new TextDecoder();
914
+ while (true) {
915
+ const { done, value } = await reader.read();
916
+ if (done) break;
917
+ text += decoder.decode(value, { stream: true });
918
+ // Stop once the server signals completion (it won't close the socket).
919
+ if (text.includes('[DONE]')) { try { await reader.cancel(); } catch (e) {} break; }
920
+ if (Date.now() > deadline) { try { await reader.cancel(); } catch (e) {} break; }
921
+ }
922
+ text += decoder.decode();
923
+ } catch (e) {
924
+ // Fall back to whatever we managed to read; parseSSEFinal handles partials.
925
+ console.error('[ChatGPT Bridge] stream read error:', e);
926
+ }
927
+ }
928
  let convId = '';
929
  const parseSSEFinal = (raw) => {
930
  let snapshot = '';