@bacnh85/pi-web 0.10.4 → 0.10.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.10.5 (2026-09-13)
4
+
5
+ ### Added
6
+
7
+ - **`GEMINI_WEB_SECURE_1PSIDTS` env** — the rotating `__Secure-1PSIDTS`
8
+ session cookie, injected into the client jar pre-init. Google stopped
9
+ serving SNlM0e/cookie rotations to plain clients; without it the session
10
+ is partially authed (chat works, `accessToken` unresolved, sensitive
11
+ surfaces refuse). With it: full auth (`accessToken` resolves).
12
+
3
13
  ## 0.10.4 (2026-09-13)
4
14
 
5
15
  ### Fixed
package/README.md CHANGED
@@ -32,6 +32,7 @@ Variables:
32
32
  | `CRAWL4AI_API_TOKEN` | No (3) | — | Required if Crawl4AI auth enabled |
33
33
  | `GEMINI_WEB_SECURE_1PSID` | No (4) | — | `__Secure-1PSID` cookie from gemini.google.com — enables authed `web_research` (Deep Research) |
34
34
  | `GEMINI_WEB_PROXY` | No | — | Proxy URL for Gemini web calls (escape hatch if Google blocks the IP) |
35
+ | `GEMINI_WEB_SECURE_1PSIDTS` | No (6) | — | Rotating `__Secure-1PSIDTS` cookie — restores full auth when Google withholds SNlM0e from plain clients (recommended for image surfaces) |
35
36
  | `ZAI_API_KEY` | No (5) | — | Z.ai API key — enables the `web_image` `zai` provider (GLM-Image via the official `api.z.ai`); `Z_AI_API_KEY` also accepted |
36
37
  | `WEB_IMAGE_API_BASE_URL` | No | — | `web_image` `custom` provider: any OpenAI-compatible images endpoint (e.g. `https://api.openai.com/v1`) |
37
38
  | `WEB_IMAGE_API_KEY` | No | — | Bearer key for the `custom` endpoint |
@@ -45,6 +46,7 @@ Variables:
45
46
  > (2) Required for hosted Firecrawl; optional for self-hosted instances without auth.
46
47
  > (3) Required for Crawl4AI v0.9+ default config.
47
48
  > (4) Without it `web_research mode=ask` still works in guest mode (Flash-only); `mode=research` errors with setup steps.
49
+ > (6) Copy the current value from DevTools (Application → Cookies) alongside `__Secure-1PSID`; it rotates, so refresh it when auth degrades.
48
50
  > (5) `web_image` works with zero config via Gemini guest mode (availability varies by region/account); `zai` activates when `ZAI_API_KEY` is present, `custom` when `WEB_IMAGE_API_BASE_URL` is set.
49
51
 
50
52
  Secrets are never printed; `web_status` reports only presence/source.
@@ -14,13 +14,15 @@ import { findEnvValue } from "./config";
14
14
  export interface GeminiWebConfig {
15
15
  psid?: string;
16
16
  psidSource: string;
17
+ psidts?: string;
17
18
  proxy?: string;
18
19
  }
19
20
 
20
21
  export function loadGeminiWebConfig(cwd = process.cwd(), includeCwdEnv = false): GeminiWebConfig {
21
22
  const psid = findEnvValue("GEMINI_WEB_SECURE_1PSID", cwd, includeCwdEnv);
23
+ const psidts = findEnvValue("GEMINI_WEB_SECURE_1PSIDTS", cwd, includeCwdEnv);
22
24
  const proxy = findEnvValue("GEMINI_WEB_PROXY", cwd, includeCwdEnv);
23
- return { psid: psid.value, psidSource: psid.value ? psid.source : "not set", proxy: proxy.value };
25
+ return { psid: psid.value, psidSource: psid.value ? psid.source : "not set", psidts: psidts.value, proxy: proxy.value };
24
26
  }
25
27
 
26
28
  // ---------------------------------------------------------------------------
@@ -66,7 +68,7 @@ export interface GeminiClientLike {
66
68
  }
67
69
 
68
70
  export type GeminiClientFactory = (
69
- opts: { secure_1psid?: string; proxy?: string },
71
+ opts: { secure_1psid?: string; secure_1psidts?: string; proxy?: string },
70
72
  ) => GeminiClientLike | Promise<GeminiClientLike>;
71
73
 
72
74
  // Cached per config (psid|proxy) so a config change re-creates the client.
@@ -137,14 +139,24 @@ export async function loadDefaultFactory(): Promise<GeminiClientFactory> {
137
139
  }
138
140
  // ponytail: generous per-request cap (covers research); per-mode ask/research
139
141
  // timeouts are enforced by raceGuard below.
140
- return (opts) => new Gemini({ secure_1psid: opts.secure_1psid, proxy: opts.proxy ?? null, timeout: 1_800_000 });
142
+ // ponytail: Google's rotating __Secure-1PSIDTS is required for sensitive
143
+ // surfaces (image generation refuses with "You might be signed out" when it
144
+ // is missing); the page HTML no longer carries SNlM0e/rotations for plain
145
+ // clients, so the user passes it explicitly and we inject it pre-init.
146
+ return (opts) => {
147
+ const client = new Gemini({ secure_1psid: opts.secure_1psid, proxy: opts.proxy ?? null, timeout: 1_800_000 });
148
+ if (opts.secure_1psidts) {
149
+ (client as unknown as { cookies: Record<string, string> }).cookies["__Secure-1PSIDTS"] = opts.secure_1psidts;
150
+ }
151
+ return client;
152
+ };
141
153
  }
142
154
 
143
155
  async function getClient(config: GeminiWebConfig, factory?: GeminiClientFactory): Promise<GeminiClientLike> {
144
- const key = `${config.psid ?? ""}|${config.proxy ?? ""}`;
156
+ const key = `${config.psid ?? ""}|${config.psidts ?? ""}|${config.proxy ?? ""}`;
145
157
  if (cached?.key === key) return cached.client;
146
158
  const make = factory ?? (await loadDefaultFactory());
147
- const client = await make({ secure_1psid: config.psid, proxy: config.proxy });
159
+ const client = await make({ secure_1psid: config.psid, secure_1psidts: config.psidts, proxy: config.proxy });
148
160
  cached = { key, client };
149
161
  return client;
150
162
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bacnh85/pi-web",
3
- "version": "0.10.4",
3
+ "version": "0.10.5",
4
4
  "description": "Pi extension for web search, page extraction, Firecrawl scraping/crawling, Crawl4AI headless browser crawling, Gemini web-tier research, free upstream image generation, and one-off gateway chat.",
5
5
  "type": "module",
6
6
  "license": "MIT",