akashyadav758 Claude Opus 4.8 (1M context) commited on
Commit
23a7459
Β·
1 Parent(s): 6d42e1f

Remove Flow agent from stack (extension, server, gateway, monitor tab)

Browse files

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

Files changed (5) hide show
  1. Dockerfile +3 -11
  2. README.md +1 -2
  3. docker-compose.yml +6 -7
  4. monitor/main.go +8 -11
  5. start_hf.sh +10 -11
Dockerfile CHANGED
@@ -1,4 +1,4 @@
1
- # Build the navigator monitor server (GPT / Gemini / Flow live view) from source.
2
  FROM golang:1.22-bookworm AS monitor-build
3
  WORKDIR /src
4
  COPY monitor/ ./
@@ -29,7 +29,6 @@ USER root
29
  # Copy extensions into the container
30
  COPY free-Chatgpt-api/gpt-extension /opt/gpt-extension
31
  COPY free-gemini-api/gemini-extension /opt/gemini-extension
32
- COPY flow-agent/Flow-extension /opt/flow-extension
33
 
34
  # 3-tab monitor binary (replaces the single-view base monitor)
35
  COPY --from=monitor-build /monitor /opt/monitor3/monitor
@@ -41,12 +40,6 @@ COPY --from=profilesync-build /profilesync /opt/profilesync/profilesync
41
  COPY --from=chatgpt-build /agent /opt/chatgpt/agent
42
  COPY free-Chatgpt-api/config.json /opt/chatgpt/config.json
43
  COPY --from=gemini-build /free-gemini-api /opt/gemini-srv/free-gemini-api
44
- COPY flow-agent/ /opt/flow-srv/
45
-
46
- # Flow server is Python (FastAPI/uvicorn). Base image has python3; add pip + deps.
47
- RUN apt-get update && apt-get install -y --no-install-recommends python3-pip && \
48
- pip3 install --no-cache-dir --break-system-packages -r /opt/flow-srv/requirements.txt && \
49
- apt-get clean && rm -rf /var/lib/apt/lists/*
50
 
51
  # Install Chrome for Testing (unbranded). Branded google-chrome-stable (>=128)
52
  # silently ignores --load-extension, so unpacked extensions never load. CfT is the
@@ -60,9 +53,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends unzip && \
60
  apt-get clean && rm -rf /var/lib/apt/lists/*
61
 
62
  # Set correct permissions and ownership
63
- RUN rm -rf /opt/flow-extension/_metadata && \
64
- chown -R 1000:1000 /opt/gpt-extension /opt/gemini-extension /opt/flow-extension /opt/chrome-linux64 /opt/monitor3 /opt/profilesync /opt/chatgpt /opt/gemini-srv /opt/flow-srv && \
65
- chmod -R 755 /opt/gpt-extension /opt/gemini-extension /opt/flow-extension /opt/chrome-linux64 /opt/monitor3 /opt/profilesync /opt/chatgpt /opt/gemini-srv /opt/flow-srv
66
 
67
  # Replace the start script with the non-root version
68
  COPY --chmod=755 start_hf.sh /start.sh
 
1
+ # Build the navigator monitor server (GPT / Gemini live view) from source.
2
  FROM golang:1.22-bookworm AS monitor-build
3
  WORKDIR /src
4
  COPY monitor/ ./
 
29
  # Copy extensions into the container
30
  COPY free-Chatgpt-api/gpt-extension /opt/gpt-extension
31
  COPY free-gemini-api/gemini-extension /opt/gemini-extension
 
32
 
33
  # 3-tab monitor binary (replaces the single-view base monitor)
34
  COPY --from=monitor-build /monitor /opt/monitor3/monitor
 
40
  COPY --from=chatgpt-build /agent /opt/chatgpt/agent
41
  COPY free-Chatgpt-api/config.json /opt/chatgpt/config.json
42
  COPY --from=gemini-build /free-gemini-api /opt/gemini-srv/free-gemini-api
 
 
 
 
 
 
43
 
44
  # Install Chrome for Testing (unbranded). Branded google-chrome-stable (>=128)
45
  # silently ignores --load-extension, so unpacked extensions never load. CfT is the
 
53
  apt-get clean && rm -rf /var/lib/apt/lists/*
54
 
55
  # Set correct permissions and ownership
56
+ RUN chown -R 1000:1000 /opt/gpt-extension /opt/gemini-extension /opt/chrome-linux64 /opt/monitor3 /opt/profilesync /opt/chatgpt /opt/gemini-srv && \
57
+ chmod -R 755 /opt/gpt-extension /opt/gemini-extension /opt/chrome-linux64 /opt/monitor3 /opt/profilesync /opt/chatgpt /opt/gemini-srv
 
58
 
59
  # Replace the start script with the non-root version
60
  COPY --chmod=755 start_hf.sh /start.sh
README.md CHANGED
@@ -27,9 +27,8 @@ automate workflows for ChatGPT, Google Gemini, and Google Flow.
27
  |-----------|-----------|-----------|--------------|
28
  | **Gpt Agent Api** | `free-Chatgpt-api/gpt-extension` | `/opt/gpt-extension` | Auto-syncs ChatGPT cookies to a local ChatGPT Free API server |
29
  | **Gemini Api Agent** | `free-gemini-api/gemini-extension` | `/opt/gemini-extension` | Auto-syncs Google Gemini cookies to a local Free Gemini API server |
30
- | **Flow Agent** | `flow-agent/Flow-extension` | `/opt/flow-extension` | Automates Google Flow β€” T2V / V2V / I2V video + T2I / I2I image generation |
31
 
32
- All three are Manifest V3 extensions with background service workers. Each subfolder
33
  also contains the matching backend server.
34
 
35
  ---
 
27
  |-----------|-----------|-----------|--------------|
28
  | **Gpt Agent Api** | `free-Chatgpt-api/gpt-extension` | `/opt/gpt-extension` | Auto-syncs ChatGPT cookies to a local ChatGPT Free API server |
29
  | **Gemini Api Agent** | `free-gemini-api/gemini-extension` | `/opt/gemini-extension` | Auto-syncs Google Gemini cookies to a local Free Gemini API server |
 
30
 
31
+ Both are Manifest V3 extensions with background service workers. Each subfolder
32
  also contains the matching backend server.
33
 
34
  ---
docker-compose.yml CHANGED
@@ -1,17 +1,16 @@
1
- # Runs the whole stack in one container: headless Chrome + 3 extensions + the monitor
2
- # (which also serves the API gateway) + the three backend servers.
3
  #
4
- # The chrome image (built from ./Dockerfile) now bakes in all three servers and start_hf.sh
5
  # launches them on localhost alongside Chrome β€” exactly what the extensions expect (they dial
6
- # 127.0.0.1:9225/9226/9227). So there are no separate server containers anymore; that would
7
  # collide on the same ports. Only port 3001 is published.
8
  #
9
  # Internal port map (all on the container's 127.0.0.1):
10
  # chrome : 9222 CDP, 9223 CDP-proxy
11
- # monitor : 3001 UI + API gateway (/gpt /gemini /flow)
12
  # chatgpt : 9225 (ws + http API)
13
  # gemini : 8000 http API, 9226 cookie-WS
14
- # flow : 8101 http API, 8100 ext-callback, 9227 cookie-WS
15
 
16
  services:
17
  chrome:
@@ -20,7 +19,7 @@ services:
20
  ports:
21
  - "3001:3001" # monitor UI + API gateway (the only published port)
22
  environment:
23
- API_KEY: ${API_KEY:-} # gates /gpt /gemini /flow; from .env. Unset = APIs disabled (503)
24
  volumes:
25
  - chrome-profile:/home/chrome/data # persists cookies/logins across restarts
26
  restart: unless-stopped
 
1
+ # Runs the whole stack in one container: headless Chrome + 2 extensions + the monitor
2
+ # (which also serves the API gateway) + the two backend servers.
3
  #
4
+ # The chrome image (built from ./Dockerfile) now bakes in both servers and start_hf.sh
5
  # launches them on localhost alongside Chrome β€” exactly what the extensions expect (they dial
6
+ # 127.0.0.1:9225/9226). So there are no separate server containers anymore; that would
7
  # collide on the same ports. Only port 3001 is published.
8
  #
9
  # Internal port map (all on the container's 127.0.0.1):
10
  # chrome : 9222 CDP, 9223 CDP-proxy
11
+ # monitor : 3001 UI + API gateway (/gpt /gemini)
12
  # chatgpt : 9225 (ws + http API)
13
  # gemini : 8000 http API, 9226 cookie-WS
 
14
 
15
  services:
16
  chrome:
 
19
  ports:
20
  - "3001:3001" # monitor UI + API gateway (the only published port)
21
  environment:
22
+ API_KEY: ${API_KEY:-} # gates /gpt /gemini; from .env. Unset = APIs disabled (503)
23
  volumes:
24
  - chrome-profile:/home/chrome/data # persists cookies/logins across restarts
25
  restart: unless-stopped
monitor/main.go CHANGED
@@ -44,7 +44,6 @@ type knownTab struct {
44
  var knownTabs = []knownTab{
45
  {"ChatGPT", "https://chatgpt.com/", "chatgpt.com"},
46
  {"Gemini", "https://gemini.google.com/", "gemini.google.com"},
47
- {"Flow", "https://labs.google/fx", "labs.google"},
48
  }
49
 
50
  // cdpTarget mirrors the relevant fields of an entry from GET /json.
@@ -487,8 +486,8 @@ func chromeLogHandler(w http.ResponseWriter, r *http.Request) {
487
  }
488
 
489
  // backendLogHandler serves the per-server logs (API-key gated) so we can diagnose
490
- // the gpt/gemini/flow backends without shelling into the container:
491
- // /logs/chatgpt /logs/gemini /logs/flow (also /logs/monitor)
492
  func backendLogHandler(w http.ResponseWriter, r *http.Request) {
493
  if !authOK(w, r) {
494
  return
@@ -497,12 +496,11 @@ func backendLogHandler(w http.ResponseWriter, r *http.Request) {
497
  paths := map[string]string{
498
  "chatgpt": "/home/chrome/chatgpt.log",
499
  "gemini": "/home/chrome/gemini.log",
500
- "flow": "/home/chrome/flow.log",
501
  "monitor": "/home/chrome/monitor.log",
502
  }
503
  p, ok := paths[name]
504
  if !ok {
505
- http.Error(w, "unknown log (use chatgpt|gemini|flow|monitor)", http.StatusNotFound)
506
  return
507
  }
508
  f, err := os.Open(p)
@@ -528,10 +526,10 @@ func statsHandler(w http.ResponseWriter, r *http.Request) {
528
  }
529
 
530
  // ---- API gateway ----------------------------------------------------------
531
- // The monitor doubles as the single public entry point for the three backend
532
  // servers that run on localhost inside this same container. HF exposes only one
533
- // port (3001), so /gpt, /gemini and /flow are reverse-proxied to the servers'
534
- // loopback HTTP ports. All three are gated by an API key (fail-closed).
535
 
536
  var apiKey = os.Getenv("API_KEY")
537
 
@@ -626,7 +624,7 @@ func main() {
626
  // HuggingFace's own auth already gates who can reach it (the owner). The browser
627
  // can't attach ?key= when HF serves the private subdomain, so requiring our key
628
  // here locks the owner out of their own live view. Only the AI gateway
629
- // (/gpt /gemini /flow) and /logs stay API-key-gated for external programmatic use.
630
  http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
631
  if r.URL.Path != "/" {
632
  http.NotFound(w, r)
@@ -651,9 +649,8 @@ func main() {
651
  // API gateway β†’ the three backend servers on localhost (API-key gated).
652
  http.HandleFunc("/gpt/", gatewayHandler("/gpt", "http://127.0.0.1:9225"))
653
  http.HandleFunc("/gemini/", gatewayHandler("/gemini", "http://127.0.0.1:8000"))
654
- http.HandleFunc("/flow/", gatewayHandler("/flow", "http://127.0.0.1:8101"))
655
  if apiKey == "" {
656
- log.Println("WARNING: API_KEY not set β€” /gpt /gemini /flow are disabled (503) until it is set")
657
  }
658
 
659
  addr := ":3001"
 
44
  var knownTabs = []knownTab{
45
  {"ChatGPT", "https://chatgpt.com/", "chatgpt.com"},
46
  {"Gemini", "https://gemini.google.com/", "gemini.google.com"},
 
47
  }
48
 
49
  // cdpTarget mirrors the relevant fields of an entry from GET /json.
 
486
  }
487
 
488
  // backendLogHandler serves the per-server logs (API-key gated) so we can diagnose
489
+ // the gpt/gemini backends without shelling into the container:
490
+ // /logs/chatgpt /logs/gemini (also /logs/monitor)
491
  func backendLogHandler(w http.ResponseWriter, r *http.Request) {
492
  if !authOK(w, r) {
493
  return
 
496
  paths := map[string]string{
497
  "chatgpt": "/home/chrome/chatgpt.log",
498
  "gemini": "/home/chrome/gemini.log",
 
499
  "monitor": "/home/chrome/monitor.log",
500
  }
501
  p, ok := paths[name]
502
  if !ok {
503
+ http.Error(w, "unknown log (use chatgpt|gemini|monitor)", http.StatusNotFound)
504
  return
505
  }
506
  f, err := os.Open(p)
 
526
  }
527
 
528
  // ---- API gateway ----------------------------------------------------------
529
+ // The monitor doubles as the single public entry point for the backend
530
  // servers that run on localhost inside this same container. HF exposes only one
531
+ // port (3001), so /gpt and /gemini are reverse-proxied to the servers'
532
+ // loopback HTTP ports. Both are gated by an API key (fail-closed).
533
 
534
  var apiKey = os.Getenv("API_KEY")
535
 
 
624
  // HuggingFace's own auth already gates who can reach it (the owner). The browser
625
  // can't attach ?key= when HF serves the private subdomain, so requiring our key
626
  // here locks the owner out of their own live view. Only the AI gateway
627
+ // (/gpt /gemini) and /logs stay API-key-gated for external programmatic use.
628
  http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
629
  if r.URL.Path != "/" {
630
  http.NotFound(w, r)
 
649
  // API gateway β†’ the three backend servers on localhost (API-key gated).
650
  http.HandleFunc("/gpt/", gatewayHandler("/gpt", "http://127.0.0.1:9225"))
651
  http.HandleFunc("/gemini/", gatewayHandler("/gemini", "http://127.0.0.1:8000"))
 
652
  if apiKey == "" {
653
+ log.Println("WARNING: API_KEY not set β€” /gpt /gemini are disabled (503) until it is set")
654
  }
655
 
656
  addr := ":3001"
start_hf.sh CHANGED
@@ -106,13 +106,12 @@ touch /home/chrome/chrome.log
106
  echo "πŸ”Œ Starting CDP Proxy..."
107
  socat TCP-LISTEN:9223,fork,bind=0.0.0.0 TCP:127.0.0.1:9222 &
108
 
109
- # 6a. Start the three backend API servers on localhost. The monitor doubles as a
110
- # gateway and fronts them on :3001 (/gpt, /gemini, /flow). Each logs separately
111
  # and runs in the background so a crash never blocks the boot.
112
- echo "🧩 Starting backend API servers (gpt / gemini / flow)..."
113
  ( cd /opt/chatgpt && ./agent >> /home/chrome/chatgpt.log 2>&1 & )
114
  ( cd /opt/gemini-srv && WS_PORT=9226 PORT=8000 ./free-gemini-api >> /home/chrome/gemini.log 2>&1 & )
115
- ( cd /opt/flow-srv && WS_PORT=9227 HTTP_PORT=8100 python3 -m uvicorn cli.api:app --host 127.0.0.1 --port 8101 >> /home/chrome/flow.log 2>&1 & )
116
 
117
  # 6b. Periodic profile backup (safety net if HF kills the container without a clean
118
  # SIGTERM). Best-effort every 5 minutes; the shutdown trap does the final one.
@@ -124,17 +123,17 @@ fi
124
  # 6c. Provide a valid per-user runtime dir. Chrome's mojo/IPC layer and each MV3
125
  # extension service worker need this; without it Chrome logs
126
  # "XDG_RUNTIME_DIR is invalid or not set" and the extension service workers
127
- # intermittently fail to spawn (DidStartWorkerFail) β†’ the gpt/gemini/flow
128
  # extensions never connect. Purely additive: just creates a dir and exports it.
129
  export XDG_RUNTIME_DIR=/tmp/runtime-chrome
130
  mkdir -p "$XDG_RUNTIME_DIR" && chmod 700 "$XDG_RUNTIME_DIR"
131
 
132
  # 7. Launch Chrome Headless
133
  # NOTE: do NOT add --renderer-process-limit=1 / --process-per-site / --no-zygote here.
134
- # Each of the 3 extensions runs an MV3 service worker (its own renderer) and the chat
135
- # flow injects via chrome.scripting.executeScript into the service tab. Capping renderers
136
  # starves those workers β€” they fail to start (DidStartWorkerFail) so the extension never
137
- # connects, and when one does start, executeScript hangs β†’ the /gpt /gemini /flow APIs
138
  # hang forever. HF cpu-basic has 16 GB (we use ~1–2 GB), so the memory "savings" weren't
139
  # needed and broke the extensions. Keep Chrome multi-process.
140
  echo "✨ Launching Chrome Headless..."
@@ -173,8 +172,8 @@ echo "✨ Launching Chrome Headless..."
173
  --disable-background-timer-throttling \
174
  --disable-renderer-backgrounding \
175
  --disable-backgrounding-occluded-windows \
176
- --load-extension=/opt/gpt-extension,/opt/gemini-extension,/opt/flow-extension \
177
- --disable-extensions-except=/opt/gpt-extension,/opt/gemini-extension,/opt/flow-extension \
178
  --disable-translate \
179
  --memory-pressure-off \
180
  --disable-client-side-phishing-detection \
@@ -193,4 +192,4 @@ echo "✨ Launching Chrome Headless..."
193
  --disable-site-isolation-trials \
194
  --js-flags="--max-old-space-size=512" \
195
  --metrics-recording-only \
196
- 'about:blank' >> /home/chrome/chrome.log 2>&1
 
106
  echo "πŸ”Œ Starting CDP Proxy..."
107
  socat TCP-LISTEN:9223,fork,bind=0.0.0.0 TCP:127.0.0.1:9222 &
108
 
109
+ # 6a. Start the backend API servers on localhost. The monitor doubles as a
110
+ # gateway and fronts them on :3001 (/gpt, /gemini). Each logs separately
111
  # and runs in the background so a crash never blocks the boot.
112
+ echo "🧩 Starting backend API servers (gpt / gemini)..."
113
  ( cd /opt/chatgpt && ./agent >> /home/chrome/chatgpt.log 2>&1 & )
114
  ( cd /opt/gemini-srv && WS_PORT=9226 PORT=8000 ./free-gemini-api >> /home/chrome/gemini.log 2>&1 & )
 
115
 
116
  # 6b. Periodic profile backup (safety net if HF kills the container without a clean
117
  # SIGTERM). Best-effort every 5 minutes; the shutdown trap does the final one.
 
123
  # 6c. Provide a valid per-user runtime dir. Chrome's mojo/IPC layer and each MV3
124
  # extension service worker need this; without it Chrome logs
125
  # "XDG_RUNTIME_DIR is invalid or not set" and the extension service workers
126
+ # intermittently fail to spawn (DidStartWorkerFail) β†’ the gpt/gemini
127
  # extensions never connect. Purely additive: just creates a dir and exports it.
128
  export XDG_RUNTIME_DIR=/tmp/runtime-chrome
129
  mkdir -p "$XDG_RUNTIME_DIR" && chmod 700 "$XDG_RUNTIME_DIR"
130
 
131
  # 7. Launch Chrome Headless
132
  # NOTE: do NOT add --renderer-process-limit=1 / --process-per-site / --no-zygote here.
133
+ # Each extension runs an MV3 service worker (its own renderer) and the chat
134
+ # pipeline injects via chrome.scripting.executeScript into the service tab. Capping renderers
135
  # starves those workers β€” they fail to start (DidStartWorkerFail) so the extension never
136
+ # connects, and when one does start, executeScript hangs β†’ the /gpt /gemini APIs
137
  # hang forever. HF cpu-basic has 16 GB (we use ~1–2 GB), so the memory "savings" weren't
138
  # needed and broke the extensions. Keep Chrome multi-process.
139
  echo "✨ Launching Chrome Headless..."
 
172
  --disable-background-timer-throttling \
173
  --disable-renderer-backgrounding \
174
  --disable-backgrounding-occluded-windows \
175
+ --load-extension=/opt/gpt-extension,/opt/gemini-extension \
176
+ --disable-extensions-except=/opt/gpt-extension,/opt/gemini-extension \
177
  --disable-translate \
178
  --memory-pressure-off \
179
  --disable-client-side-phishing-detection \
 
192
  --disable-site-isolation-trials \
193
  --js-flags="--max-old-space-size=512" \
194
  --metrics-recording-only \
195
+ 'https://chatgpt.com/' >> /home/chrome/chrome.log 2>&1