@love-moon/chat-web 0.17.0 → 0.17.2

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.
Files changed (39) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/dist/core/broker-protocol.d.ts +13 -0
  3. package/dist/core/broker-protocol.js +29 -0
  4. package/dist/core/broker-protocol.js.map +1 -0
  5. package/dist/core/broker-worker.d.ts +1 -0
  6. package/dist/core/broker-worker.js +105 -0
  7. package/dist/core/broker-worker.js.map +1 -0
  8. package/dist/core/errors.d.ts +1 -1
  9. package/dist/core/errors.js.map +1 -1
  10. package/dist/core/provider.d.ts +4 -0
  11. package/dist/core/provider.js.map +1 -1
  12. package/dist/core/turn-broker.d.ts +12 -0
  13. package/dist/core/turn-broker.js +331 -0
  14. package/dist/core/turn-broker.js.map +1 -0
  15. package/dist/core/turn-queue.d.ts +12 -0
  16. package/dist/core/turn-queue.js +54 -0
  17. package/dist/core/turn-queue.js.map +1 -0
  18. package/dist/index.d.ts +4 -2
  19. package/dist/index.js +4 -2
  20. package/dist/index.js.map +1 -1
  21. package/dist/providers/chatgpt.d.ts +1 -0
  22. package/dist/providers/chatgpt.js +6 -0
  23. package/dist/providers/chatgpt.js.map +1 -1
  24. package/dist/providers/gemini.d.ts +1 -0
  25. package/dist/providers/gemini.js +5 -0
  26. package/dist/providers/gemini.js.map +1 -1
  27. package/dist/providers/index.d.ts +1 -0
  28. package/dist/providers/index.js +3 -0
  29. package/dist/providers/index.js.map +1 -1
  30. package/dist/providers/kimi.d.ts +38 -0
  31. package/dist/providers/kimi.js +270 -0
  32. package/dist/providers/kimi.js.map +1 -0
  33. package/dist/queued-session.d.ts +31 -0
  34. package/dist/queued-session.js +224 -0
  35. package/dist/queued-session.js.map +1 -0
  36. package/dist/session.d.ts +5 -0
  37. package/dist/session.js +14 -3
  38. package/dist/session.js.map +1 -1
  39. package/package.json +2 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,33 @@
1
1
  # @love-moon/chat-web
2
2
 
3
+ ## 0.17.2
4
+
5
+ ### Patch Changes
6
+
7
+ - b124565: Add QueuedChatSession with a shared local browser broker and a FIFO turn queue
8
+ across processes. Each task retains its own conversation tab; idle tasks no
9
+ longer hold exclusive access to the provider profile. The AI SDK uses queued
10
+ sessions when available and reports waiting positions through working status.
11
+
12
+ Cancel pending turns on disconnect, stop/close failed conversation tabs before
13
+ advancing the queue, and release the browser after its last client exits.
14
+ Keep the exclusive ChatSession API available for direct Playwright access.
15
+
16
+ Keep logical sessions usable after an active stop, timeout, or provider failure.
17
+ Restore the original provider conversation for the next explicit user operation;
18
+ require explicit clear when safe restoration is unavailable, and never replay a
19
+ failed prompt. Allow clear after a failed first submission. Correct the Windows
20
+ named-pipe address escaping.
21
+
22
+ - 0a9488e: Add Kimi website text conversations with persistent login, multi-turn context,
23
+ reply progress, new chats and browser diagnostics. Expose the provider through
24
+ ai-sdk's chat-web backend and the web-kimi Conductor configuration alias.
25
+
26
+ Explicit unknown chat-web providers now fail with a clear error instead of
27
+ silently opening ChatGPT. The existing kimi CLI backend is unchanged.
28
+
29
+ ## 0.17.1
30
+
3
31
  ## 0.17.0
4
32
 
5
33
  ## 0.16.0
@@ -0,0 +1,13 @@
1
+ export declare const BROKER_PROTOCOL = 1;
2
+ export declare function brokerPaths(provider: string): {
3
+ socket: string;
4
+ lock: string;
5
+ };
6
+ export interface WireError {
7
+ name: string;
8
+ message: string;
9
+ code?: string;
10
+ provider?: string;
11
+ hint?: string;
12
+ }
13
+ export declare function wireError(error: unknown): WireError;
@@ -0,0 +1,29 @@
1
+ import { createHash } from "node:crypto";
2
+ import fs from "node:fs";
3
+ import os from "node:os";
4
+ import path from "node:path";
5
+ import { profileDir } from "./paths.js";
6
+ export const BROKER_PROTOCOL = 1;
7
+ export function brokerPaths(provider) {
8
+ const profile = profileDir(provider);
9
+ fs.mkdirSync(profile, { recursive: true });
10
+ const key = createHash("sha256").update(fs.realpathSync(profile)).digest("hex").slice(0, 24);
11
+ let dir = path.join(os.tmpdir(), `cw-${process.getuid?.() ?? "user"}`);
12
+ if (process.platform !== "win32" && path.join(dir, `${key}.sock`).length > 100) {
13
+ dir = path.join("/tmp", `cw-${process.getuid?.() ?? "user"}`);
14
+ }
15
+ fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
16
+ const stat = fs.lstatSync(dir);
17
+ if (!stat.isDirectory() || (process.getuid && stat.uid !== process.getuid())) {
18
+ throw new Error(`Unsafe chat-web broker directory: ${dir}`);
19
+ }
20
+ return {
21
+ socket: process.platform === "win32" ? String.raw `\\.\pipe\chat-web-${key}` : path.join(dir, `${key}.sock`),
22
+ lock: path.join(dir, `${key}.lock`),
23
+ };
24
+ }
25
+ export function wireError(error) {
26
+ const e = error;
27
+ return { name: e?.name ?? "Error", message: e?.message ?? String(error), code: e?.code, provider: e?.provider, hint: e?.hint };
28
+ }
29
+ //# sourceMappingURL=broker-protocol.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"broker-protocol.js","sourceRoot":"","sources":["../../src/core/broker-protocol.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC;AAEjC,MAAM,UAAU,WAAW,CAAC,QAAgB;IAC1C,MAAM,OAAO,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;IACrC,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3C,MAAM,GAAG,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC7F,IAAI,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,MAAM,OAAO,CAAC,MAAM,EAAE,EAAE,IAAI,MAAM,EAAE,CAAC,CAAC;IACvE,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;QAC/E,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,OAAO,CAAC,MAAM,EAAE,EAAE,IAAI,MAAM,EAAE,CAAC,CAAC;IAChE,CAAC;IACD,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACpD,MAAM,IAAI,GAAG,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IAC/B,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,IAAI,CAAC,GAAG,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC;QAC7E,MAAM,IAAI,KAAK,CAAC,qCAAqC,GAAG,EAAE,CAAC,CAAC;IAC9D,CAAC;IACD,OAAO;QACL,MAAM,EAAE,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAA,qBAAqB,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC;QAC3G,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC;KACpC,CAAC;AACJ,CAAC;AAUD,MAAM,UAAU,SAAS,CAAC,KAAc;IACtC,MAAM,CAAC,GAAG,KAA2B,CAAC;IACtC,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,IAAI,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC;AACjI,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,105 @@
1
+ import fs from "node:fs";
2
+ import { launchProviderBrowser } from "./browser.js";
3
+ import { brokerPaths } from "./broker-protocol.js";
4
+ import { getProvider } from "./provider.js";
5
+ import { clearProfileOwner } from "./profile-lock.js";
6
+ import { profileDir } from "./paths.js";
7
+ import { startTurnBroker } from "./turn-broker.js";
8
+ import { registerBuiltinProviders } from "../providers/index.js";
9
+ const providerName = process.argv[2];
10
+ const options = JSON.parse(process.argv[3] ?? "{}");
11
+ const paths = brokerPaths(providerName);
12
+ function alive(pid) {
13
+ try {
14
+ process.kill(pid, 0);
15
+ return true;
16
+ }
17
+ catch (error) {
18
+ return error.code === "EPERM";
19
+ }
20
+ }
21
+ /** The broker holds this startup lock until its socket/browser have closed. */
22
+ function acquire() {
23
+ for (let attempt = 0; attempt < 3; attempt++) {
24
+ try {
25
+ const fd = fs.openSync(paths.lock, "wx", 0o600);
26
+ try {
27
+ fs.writeFileSync(fd, JSON.stringify({ pid: process.pid }));
28
+ }
29
+ finally {
30
+ fs.closeSync(fd);
31
+ }
32
+ return true;
33
+ }
34
+ catch (error) {
35
+ if (error.code !== "EEXIST")
36
+ throw error;
37
+ try {
38
+ const stat = fs.statSync(paths.lock);
39
+ const text = fs.readFileSync(paths.lock, "utf8");
40
+ let pid;
41
+ try {
42
+ pid = JSON.parse(text).pid;
43
+ }
44
+ catch {
45
+ pid = 0;
46
+ }
47
+ // Another process may have just created the file but not written it.
48
+ if (!Number.isInteger(pid) || pid <= 0) {
49
+ if (Date.now() - stat.mtimeMs < 30_000)
50
+ return false;
51
+ }
52
+ else if (alive(pid))
53
+ return false;
54
+ const current = fs.statSync(paths.lock);
55
+ if (current.ino !== stat.ino || fs.readFileSync(paths.lock, "utf8") !== text)
56
+ continue;
57
+ fs.unlinkSync(paths.lock);
58
+ }
59
+ catch (error) {
60
+ if (error.code !== "ENOENT")
61
+ throw error;
62
+ }
63
+ }
64
+ }
65
+ return false;
66
+ }
67
+ if (acquire()) {
68
+ let ownsBrowser = false;
69
+ try {
70
+ if (process.platform !== "win32")
71
+ fs.rmSync(paths.socket, { force: true });
72
+ registerBuiltinProviders();
73
+ const provider = getProvider(providerName);
74
+ const broker = await startTurnBroker({
75
+ socketPath: paths.socket,
76
+ provider,
77
+ launch: async () => {
78
+ const launched = await launchProviderBrowser(providerName, { headless: options.headless, ...options.launch });
79
+ ownsBrowser = true;
80
+ return launched;
81
+ },
82
+ });
83
+ let closing = false;
84
+ const shutdown = () => {
85
+ if (closing)
86
+ return;
87
+ closing = true;
88
+ const force = setTimeout(() => process.exit(1), 10_000);
89
+ force.unref();
90
+ void broker.close();
91
+ };
92
+ process.on("SIGTERM", shutdown);
93
+ process.on("SIGINT", shutdown);
94
+ await broker.closed;
95
+ }
96
+ finally {
97
+ if (ownsBrowser)
98
+ clearProfileOwner(profileDir(providerName));
99
+ fs.rmSync(paths.lock, { force: true });
100
+ }
101
+ }
102
+ // Detached broker workers own no useful work after shutdown. An adapter's
103
+ // abandoned SSE timer must not keep an empty worker alive for several minutes.
104
+ process.exit(0);
105
+ //# sourceMappingURL=broker-worker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"broker-worker.js","sourceRoot":"","sources":["../../src/core/broker-worker.ts"],"names":[],"mappings":"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"}
@@ -5,7 +5,7 @@
5
5
  * field (human-friendly next action), so CLI / daemon callers can both
6
6
  * branch on the code and surface a useful remediation step.
7
7
  */
8
- export type ChatWebErrorCode = "NOT_LOGGED_IN" | "INPUT_NOT_FOUND" | "SEND_BUTTON_NOT_FOUND" | "RESPONSE_TIMEOUT" | "RESPONSE_EXTRACTION" | "PROVIDER_RATE_LIMITED" | "PROVIDER_CAPTCHA" | "PROVIDER_API_KEY_REQUIRED" | "PROVIDER_PERMISSION_DENIED" | "PROVIDER_AUTOMATION_BLOCKED" | "SELECTOR_VERIFICATION" | "UNKNOWN_PROVIDER" | "PROFILE_ERROR" | "PROFILE_LOCKED" | "BROWSER_LAUNCH_FAILED";
8
+ export type ChatWebErrorCode = "BROKER_UNAVAILABLE" | "BROKER_SESSION_CLOSED" | "BROKER_RECOVERY_REQUIRED" | "NOT_LOGGED_IN" | "INPUT_NOT_FOUND" | "SEND_BUTTON_NOT_FOUND" | "RESPONSE_TIMEOUT" | "RESPONSE_EXTRACTION" | "PROVIDER_RATE_LIMITED" | "PROVIDER_CAPTCHA" | "PROVIDER_API_KEY_REQUIRED" | "PROVIDER_PERMISSION_DENIED" | "PROVIDER_AUTOMATION_BLOCKED" | "SELECTOR_VERIFICATION" | "UNKNOWN_PROVIDER" | "PROFILE_ERROR" | "PROFILE_LOCKED" | "BROWSER_LAUNCH_FAILED";
9
9
  export declare class ChatWebError extends Error {
10
10
  readonly code: ChatWebErrorCode;
11
11
  readonly hint?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/core/errors.ts"],"names":[],"mappings":"AAwBA,MAAM,OAAO,YAAa,SAAQ,KAAK;IAC5B,IAAI,CAAmB;IACvB,IAAI,CAAU;IACd,QAAQ,CAAU;IAE3B,YACE,IAAsB,EACtB,OAAe,EACf,UAAiE,EAAE;QAEnE,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;QAC3B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;QACzB,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;QACjC,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAC/B,IAA4B,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QACtD,CAAC;IACH,CAAC;CACF;AAED,MAAM,OAAO,gBAAiB,SAAQ,YAAY;IAChD,YAAY,QAAgB;QAC1B,KAAK,CAAC,eAAe,EAAE,aAAa,QAAQ,qBAAqB,EAAE;YACjE,QAAQ;YACR,IAAI,EAAE,uBAAuB,QAAQ,EAAE;SACxC,CAAC,CAAC;QACH,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;IACjC,CAAC;CACF;AAED,MAAM,OAAO,kBAAmB,SAAQ,YAAY;IAClD,YAAY,QAAgB;QAC1B,KAAK,CAAC,iBAAiB,EAAE,uCAAuC,QAAQ,IAAI,EAAE;YAC5E,QAAQ;YACR,IAAI,EAAE,wBAAwB,QAAQ,aAAa;SACpD,CAAC,CAAC;QACH,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;IACnC,CAAC;CACF;AAED,MAAM,OAAO,uBAAwB,SAAQ,YAAY;IACvD,YAAY,QAAgB;QAC1B,KAAK,CAAC,uBAAuB,EAAE,yCAAyC,QAAQ,IAAI,EAAE;YACpF,QAAQ;YACR,IAAI,EAAE,wBAAwB,QAAQ,aAAa;SACpD,CAAC,CAAC;QACH,IAAI,CAAC,IAAI,GAAG,yBAAyB,CAAC;IACxC,CAAC;CACF;AAED,MAAM,OAAO,oBAAqB,SAAQ,YAAY;IACpD,YAAY,QAAgB,EAAE,SAAiB;QAC7C,KAAK,CACH,kBAAkB,EAClB,mBAAmB,SAAS,mBAAmB,QAAQ,aAAa,EACpE;YACE,QAAQ;YACR,IAAI,EAAE,qBAAqB,QAAQ,cAAc,SAAS,GAAG,CAAC,QAAQ;SACvE,CACF,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;IACrC,CAAC;CACF;AAED,MAAM,OAAO,uBAAwB,SAAQ,YAAY;IACvD,YAAY,QAAgB,EAAE,OAAO,GAAG,sCAAsC;QAC5E,KAAK,CAAC,qBAAqB,EAAE,OAAO,EAAE;YACpC,QAAQ;YACR,IAAI,EAAE,wBAAwB,QAAQ,aAAa;SACpD,CAAC,CAAC;QACH,IAAI,CAAC,IAAI,GAAG,yBAAyB,CAAC;IACxC,CAAC;CACF;AAED,MAAM,OAAO,wBAAyB,SAAQ,YAAY;IACxD,YAAY,QAAgB;QAC1B,KAAK,CAAC,uBAAuB,EAAE,aAAa,QAAQ,mCAAmC,EAAE;YACvF,QAAQ;YACR,IAAI,EAAE,gEAAgE;SACvE,CAAC,CAAC;QACH,IAAI,CAAC,IAAI,GAAG,0BAA0B,CAAC;IACzC,CAAC;CACF;AAED,MAAM,OAAO,oBAAqB,SAAQ,YAAY;IACpD,YAAY,QAAgB;QAC1B,KAAK,CAAC,kBAAkB,EAAE,aAAa,QAAQ,qCAAqC,EAAE;YACpF,QAAQ;YACR,IAAI,EAAE,uBAAuB,QAAQ,wDAAwD;SAC9F,CAAC,CAAC;QACH,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;IACrC,CAAC;CACF;AAED,MAAM,OAAO,2BAA4B,SAAQ,YAAY;IAC3D,YAAY,QAAgB,EAAE,MAAe;QAC3C,MAAM,IAAI,GAAG,aAAa,QAAQ,mDAAmD,CAAC;QACtF,KAAK,CAAC,2BAA2B,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE;YACtE,QAAQ;YACR,IAAI,EACF,QAAQ,KAAK,QAAQ;gBACnB,CAAC,CAAC,sEAAsE;oBACtE,wEAAwE;oBACxE,iFAAiF;oBACjF,kFAAkF;oBAClF,6BAA6B;gBAC/B,CAAC,CAAC,4BAA4B,QAAQ,sBAAsB;SACjE,CAAC,CAAC;QACH,IAAI,CAAC,IAAI,GAAG,6BAA6B,CAAC;IAC5C,CAAC;CACF;AAED,MAAM,OAAO,8BAA+B,SAAQ,YAAY;IAC9D,YAAY,QAAgB,EAAE,MAAe;QAC3C,MAAM,IAAI,GACR,aAAa,QAAQ,4CAA4C;YACjE,2GAA2G,CAAC;QAC9G,KAAK,CACH,6BAA6B,EAC7B,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,EACnC;YACE,QAAQ;YACR,IAAI,EACF,QAAQ,KAAK,QAAQ;gBACnB,CAAC,CAAC,iFAAiF;oBACjF,uEAAuE;oBACvE,6GAA6G;oBAC7G,mHAAmH;oBACnH,uDAAuD;gBACzD,CAAC,CAAC,iGAAiG;SACxG,CACF,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,gCAAgC,CAAC;IAC/C,CAAC;CACF;AAED,MAAM,OAAO,6BAA8B,SAAQ,YAAY;IAC7D,YAAY,QAAgB,EAAE,MAAe;QAC3C,MAAM,IAAI,GAAG,aAAa,QAAQ,2CAA2C,CAAC;QAC9E,KAAK,CAAC,4BAA4B,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE;YACvE,QAAQ;YACR,IAAI,EACF,4JAA4J;SAC/J,CAAC,CAAC;QACH,IAAI,CAAC,IAAI,GAAG,+BAA+B,CAAC;IAC9C,CAAC;CACF;AAED,MAAM,OAAO,yBAA0B,SAAQ,YAAY;IACzD,YAAY,QAAgB,EAAE,IAAY;QACxC,KAAK,CACH,uBAAuB,EACvB,qCAAqC,QAAQ,mBAAmB,IAAI,GAAG,EACvE;YACE,QAAQ;YACR,IAAI,EAAE,wBAAwB,QAAQ,aAAa;SACpD,CACF,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,2BAA2B,CAAC;IAC1C,CAAC;CACF;AAED,MAAM,OAAO,oBAAqB,SAAQ,YAAY;IACpD,YAAY,QAAgB,EAAE,KAAwB;QACpD,KAAK,CACH,kBAAkB,EAClB,qBAAqB,QAAQ,uBAAuB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EACtE,EAAE,QAAQ,EAAE,IAAI,EAAE,eAAe,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CACtD,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;IACrC,CAAC;CACF;AAED,MAAM,OAAO,YAAa,SAAQ,YAAY;IAC5C,YAAY,QAAgB,EAAE,OAAe,EAAE,KAAe;QAC5D,KAAK,CAAC,eAAe,EAAE,OAAO,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;QACrD,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;IAC7B,CAAC;CACF;AAED,MAAM,OAAO,kBAAmB,SAAQ,YAAY;IAClD,YAAY,QAAgB,EAAE,UAAkB,EAAE,QAAgB;QAChE,KAAK,CACH,gBAAgB,EAChB,aAAa,QAAQ,oCAAoC;YACvD,iBAAiB,UAAU,kBAAkB,QAAQ,KAAK;YAC1D,2DAA2D,EAC7D;YACE,QAAQ;YACR,IAAI,EACF,wBAAwB,QAAQ,sCAAsC;gBACtE,iBAAiB,QAAQ,4BAA4B;SACxD,CACF,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;IACnC,CAAC;CACF;AAED,MAAM,OAAO,kBAAmB,SAAQ,YAAY;IAClD,YAAY,QAAgB,EAAE,OAAe,EAAE,KAAe;QAC5D,KAAK,CAAC,uBAAuB,EAAE,OAAO,EAAE;YACtC,QAAQ;YACR,KAAK;YACL,IAAI,EAAE,6DAA6D;SACpE,CAAC,CAAC;QACH,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;IACnC,CAAC;CACF"}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/core/errors.ts"],"names":[],"mappings":"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"}
@@ -27,6 +27,10 @@ export interface ChatProvider {
27
27
  waitForResponse(page: Page, options?: WaitOptions): Promise<string>;
28
28
  extractLastAssistantMessage(page: Page): Promise<string>;
29
29
  newChat?(page: Page): Promise<void>;
30
+ /** Load an existing conversation without resending any message. */
31
+ resumeConversation?(page: Page, conversationId: string): Promise<void>;
32
+ /** Best-effort website-side stop before a broker disposes a failed turn. */
33
+ stopGeneration?(page: Page): Promise<void>;
30
34
  /** For doctor: cheap summary numbers (counts + booleans). */
31
35
  diagnose?(page: Page): Promise<ProviderDiagnostics>;
32
36
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"provider.js","sourceRoot":"","sources":["../../src/core/provider.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AA8DnD,MAAM,gBAAgB;IACZ,SAAS,GAAG,IAAI,GAAG,EAAwB,CAAC;IAEpD,QAAQ,CAAC,QAAsB;QAC7B,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAC9C,CAAC;IAED,GAAG,CAAC,IAAY;QACd,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC1C,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,IAAI,oBAAoB,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QACnE,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,GAAG,CAAC,IAAY;QACd,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC;IAED,IAAI;QACF,OAAO,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC;IACpC,CAAC;CACF;AAED,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,gBAAgB,EAAE,CAAC;AAEvD,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,OAAO,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,QAAsB;IACrD,gBAAgB,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AACtC,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,OAAO,gBAAgB,CAAC,IAAI,EAAE,CAAC;AACjC,CAAC"}
1
+ {"version":3,"file":"provider.js","sourceRoot":"","sources":["../../src/core/provider.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAkEnD,MAAM,gBAAgB;IACZ,SAAS,GAAG,IAAI,GAAG,EAAwB,CAAC;IAEpD,QAAQ,CAAC,QAAsB;QAC7B,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAC9C,CAAC;IAED,GAAG,CAAC,IAAY;QACd,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC1C,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,IAAI,oBAAoB,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QACnE,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,GAAG,CAAC,IAAY;QACd,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC;IAED,IAAI;QACF,OAAO,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC;IACpC,CAAC;CACF;AAED,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,gBAAgB,EAAE,CAAC;AAEvD,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,OAAO,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,QAAsB;IACrD,gBAAgB,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AACtC,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,OAAO,gBAAgB,CAAC,IAAI,EAAE,CAAC;AACjC,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { LaunchedBrowser } from "./browser.js";
2
+ import type { ChatProvider } from "./provider.js";
3
+ /** One profile, one browser, one FIFO; each connection owns a separate tab. */
4
+ export declare function startTurnBroker(options: {
5
+ socketPath: string;
6
+ provider: ChatProvider;
7
+ launch: () => Promise<LaunchedBrowser>;
8
+ idleMs?: number;
9
+ }): Promise<{
10
+ close(): Promise<void>;
11
+ closed: Promise<void>;
12
+ }>;
@@ -0,0 +1,331 @@
1
+ import fs from "node:fs";
2
+ import net from "node:net";
3
+ import readline from "node:readline";
4
+ import { BROKER_PROTOCOL, wireError } from "./broker-protocol.js";
5
+ import { ChatWebError, NotLoggedInError, ResponseTimeoutError } from "./errors.js";
6
+ import { TurnQueue } from "./turn-queue.js";
7
+ import { ChatSession } from "../session.js";
8
+ // Some adapters wait on a network collector that does not observe AbortSignal.
9
+ // The broker must still release a disconnected task after its page is closed.
10
+ async function withTurnDeadline(run, controller, timeoutMs, provider) {
11
+ let timer;
12
+ let abort;
13
+ try {
14
+ return await new Promise((resolve, reject) => {
15
+ abort = () => reject(new DOMException("Aborted", "AbortError"));
16
+ if (controller.signal.aborted) {
17
+ abort();
18
+ return;
19
+ }
20
+ controller.signal.addEventListener("abort", abort, { once: true });
21
+ timer = setTimeout(() => {
22
+ reject(new ResponseTimeoutError(provider, timeoutMs));
23
+ controller.abort();
24
+ }, timeoutMs);
25
+ void Promise.resolve().then(run).then(resolve, reject);
26
+ });
27
+ }
28
+ finally {
29
+ if (timer)
30
+ clearTimeout(timer);
31
+ if (abort)
32
+ controller.signal.removeEventListener("abort", abort);
33
+ }
34
+ }
35
+ /** One profile, one browser, one FIFO; each connection owns a separate tab. */
36
+ export async function startTurnBroker(options) {
37
+ const { provider } = options;
38
+ const queue = new TurnQueue();
39
+ const clients = new Set();
40
+ let browser;
41
+ let idleTimer;
42
+ let stopping = false;
43
+ let closePromise;
44
+ let resolveClosed;
45
+ const closed = new Promise((resolve) => { resolveClosed = resolve; });
46
+ const send = (client, message) => {
47
+ if (!client.socket.destroyed && !client.socket.writableEnded)
48
+ client.socket.write(`${JSON.stringify(message)}\n`);
49
+ };
50
+ // Retire a failed page while keeping the logical conversation/connection.
51
+ // No failed prompt is replayed: only a later user operation restores the URL.
52
+ const retirePage = (client, preserveConversation) => {
53
+ if (client.disposal)
54
+ return client.disposal;
55
+ const session = client.session;
56
+ if (!session)
57
+ return Promise.resolve();
58
+ const previousId = client.recoveryId;
59
+ const recovering = client.needsRecovery;
60
+ client.session = undefined;
61
+ client.needsRecovery = true;
62
+ client.recoveryId = undefined;
63
+ if (preserveConversation) {
64
+ try {
65
+ client.recoveryId = recovering ? previousId : provider.getConversationId?.(session.page) ?? previousId;
66
+ }
67
+ catch { /* Require explicit clear if the ID is unknown. */ }
68
+ }
69
+ client.disposal = (async () => {
70
+ try {
71
+ await provider.stopGeneration?.(session.page);
72
+ }
73
+ catch { /* Close the page regardless. */ }
74
+ await session.close();
75
+ })();
76
+ return client.disposal;
77
+ };
78
+ const dispose = (client) => {
79
+ client.closing = true;
80
+ for (const controller of client.jobs.values())
81
+ controller.abort();
82
+ return retirePage(client, false);
83
+ };
84
+ const assertConnected = (client) => {
85
+ if (client.closing || !client.opened) {
86
+ throw new ChatWebError("BROKER_SESSION_CLOSED", "The shared chat-web session is closed; create a new session.", { provider: provider.name });
87
+ }
88
+ };
89
+ const recoveryRequired = () => new ChatWebError("BROKER_RECOVERY_REQUIRED", "Could not restore the previous conversation safely. No message was sent. Use /clear to explicitly start a new conversation.", { provider: provider.name, hint: "Use newChat() or /clear; the failed message will not be retried." });
90
+ const createSession = async (client, signal) => {
91
+ if (client.disposal)
92
+ await client.disposal;
93
+ browser ??= options.launch().then((launched) => {
94
+ launched.context.once?.("close", () => { void close(); });
95
+ return launched;
96
+ });
97
+ const launched = await browser;
98
+ if (client.closing || signal?.aborted)
99
+ throw new DOMException("Aborted", "AbortError");
100
+ const page = await launched.context.newPage();
101
+ if (client.closing || signal?.aborted) {
102
+ await page.close();
103
+ throw new DOMException("Aborted", "AbortError");
104
+ }
105
+ client.disposal = undefined;
106
+ client.session = ChatSession.fromBrowser({
107
+ provider, page, context: launched.context, userDataDir: launched.userDataDir, closeContext: false,
108
+ });
109
+ if (client.closing) {
110
+ await dispose(client);
111
+ throw new DOMException("Aborted", "AbortError");
112
+ }
113
+ return client.session;
114
+ };
115
+ const ensureSession = async (client, discardConversation = false, signal) => {
116
+ assertConnected(client);
117
+ if (client.session && !client.session.isClosed)
118
+ return client.session;
119
+ const targetId = client.recoveryId;
120
+ if (!discardConversation && (!targetId || !provider.resumeConversation))
121
+ throw recoveryRequired();
122
+ const session = await createSession(client, signal);
123
+ try {
124
+ if (discardConversation)
125
+ await provider.open(session.page);
126
+ else {
127
+ await provider.resumeConversation(session.page, targetId);
128
+ if (!await session.isLoggedIn())
129
+ throw new NotLoggedInError(provider.name);
130
+ if (provider.getConversationId?.(session.page) !== targetId)
131
+ throw recoveryRequired();
132
+ }
133
+ if (signal?.aborted)
134
+ throw new DOMException("Aborted", "AbortError");
135
+ client.needsRecovery = false;
136
+ return session;
137
+ }
138
+ catch (error) {
139
+ // A timed-out restore may finish after the next turn has started.
140
+ // It must never retire that newer page or overwrite its recovery state.
141
+ if (client.session === session) {
142
+ await retirePage(client, false);
143
+ client.recoveryId = discardConversation ? undefined : targetId;
144
+ }
145
+ throw error;
146
+ }
147
+ };
148
+ const perform = async (client, request) => {
149
+ const { id, method } = request;
150
+ const args = request.args ?? {};
151
+ if (method === "close") {
152
+ await dispose(client);
153
+ send(client, { id, result: null });
154
+ return;
155
+ }
156
+ if (client.closing)
157
+ assertConnected(client);
158
+ if (method === "open") {
159
+ if (args.protocol !== BROKER_PROTOCOL)
160
+ throw new Error("Incompatible chat-web broker protocol; close existing chat-web sessions and retry.");
161
+ if (client.opening || client.session)
162
+ throw new Error("This broker connection already owns a session.");
163
+ client.opening = true;
164
+ }
165
+ const controller = new AbortController();
166
+ client.jobs.set(id, controller);
167
+ try {
168
+ let result;
169
+ if (method === "open") {
170
+ result = await queue.run(async () => {
171
+ const session = await createSession(client);
172
+ try {
173
+ if (args.autoOpen !== false)
174
+ await provider.open(session.page);
175
+ client.opened = true;
176
+ return { userDataDir: session.userDataDir };
177
+ }
178
+ catch (error) {
179
+ await dispose(client);
180
+ throw error;
181
+ }
182
+ }, { signal: controller.signal });
183
+ }
184
+ else if (method === "send" || method === "newChat") {
185
+ result = await queue.run(async () => {
186
+ try {
187
+ const timeoutMs = typeof args.timeoutMs === "number" && Number.isFinite(args.timeoutMs) && args.timeoutMs > 0
188
+ ? args.timeoutMs : 180_000;
189
+ const result = await withTurnDeadline(async () => {
190
+ const session = await ensureSession(client, method === "newChat" || args.newChat === true, controller.signal);
191
+ if (controller.signal.aborted)
192
+ throw new DOMException("Aborted", "AbortError");
193
+ await session.page.bringToFront();
194
+ if (controller.signal.aborted)
195
+ throw new DOMException("Aborted", "AbortError");
196
+ if (method === "newChat") {
197
+ await session.newChat();
198
+ return null;
199
+ }
200
+ const sendOptions = {
201
+ timeoutMs,
202
+ stableMs: typeof args.stableMs === "number" ? args.stableMs : undefined,
203
+ newChat: args.newChat === true,
204
+ signal: controller.signal,
205
+ onProgress: (text) => send(client, { id, type: "progress", text }),
206
+ };
207
+ return await session.send(String(args.message ?? ""), sendOptions);
208
+ }, controller, timeoutMs, provider.name);
209
+ // Update logical state only after success, never from a late result
210
+ // of an operation that already timed out or was cancelled.
211
+ if (method === "newChat") {
212
+ client.turnCounter = 0;
213
+ client.recoveryId = undefined;
214
+ }
215
+ else {
216
+ const turn = result;
217
+ if (args.newChat === true)
218
+ client.turnCounter = 0;
219
+ turn.turnIndex = client.turnCounter++;
220
+ client.recoveryId = turn.conversationId;
221
+ }
222
+ return result;
223
+ }
224
+ catch (error) {
225
+ await retirePage(client, method === "send" && args.newChat !== true);
226
+ throw error;
227
+ }
228
+ }, {
229
+ signal: controller.signal,
230
+ onPosition: (position) => send(client, { id, type: "queue", position }),
231
+ });
232
+ }
233
+ else if (method === "isLoggedIn") {
234
+ result = client.session && !client.needsRecovery
235
+ ? await client.session.isLoggedIn()
236
+ : await queue.run(async () => (await ensureSession(client)).isLoggedIn(), { signal: controller.signal });
237
+ }
238
+ else if (method === "diagnose") {
239
+ result = client.session && !client.needsRecovery
240
+ ? await client.session.diagnose()
241
+ : await queue.run(async () => (await ensureSession(client)).diagnose(), { signal: controller.signal });
242
+ }
243
+ else if (method === "snapshot") {
244
+ result = client.session && !client.needsRecovery
245
+ ? await client.session.snapshot()
246
+ : await queue.run(async () => (await ensureSession(client)).snapshot(), { signal: controller.signal });
247
+ }
248
+ else {
249
+ throw new Error(`Unknown chat-web broker method: ${method}`);
250
+ }
251
+ send(client, { id, result });
252
+ }
253
+ finally {
254
+ client.jobs.delete(id);
255
+ }
256
+ };
257
+ const server = net.createServer((socket) => {
258
+ if (stopping) {
259
+ socket.destroy();
260
+ return;
261
+ }
262
+ if (idleTimer)
263
+ clearTimeout(idleTimer);
264
+ const client = { socket, opening: false, opened: false, closing: false, needsRecovery: false, turnCounter: 0, jobs: new Map() };
265
+ clients.add(client);
266
+ socket.on("error", () => { socket.destroy(); });
267
+ const lines = readline.createInterface({ input: socket });
268
+ lines.on("error", () => socket.destroy());
269
+ lines.on("line", (line) => {
270
+ let request;
271
+ try {
272
+ request = JSON.parse(line);
273
+ }
274
+ catch {
275
+ socket.destroy();
276
+ return;
277
+ }
278
+ if (!Number.isSafeInteger(request.id)) {
279
+ socket.destroy();
280
+ return;
281
+ }
282
+ if (request.type === "cancel") {
283
+ client.jobs.get(request.id)?.abort();
284
+ return;
285
+ }
286
+ void perform(client, request).catch((error) => send(client, { id: request.id, error: wireError(error) }));
287
+ });
288
+ socket.once("close", () => {
289
+ lines.close();
290
+ void dispose(client).finally(() => {
291
+ clients.delete(client);
292
+ scheduleIdle();
293
+ });
294
+ });
295
+ });
296
+ const close = () => {
297
+ closePromise ??= (async () => {
298
+ stopping = true;
299
+ if (idleTimer)
300
+ clearTimeout(idleTimer);
301
+ for (const client of clients)
302
+ client.socket.destroy();
303
+ await Promise.all([...clients].map(dispose));
304
+ await new Promise((resolve) => server.close(() => resolve()));
305
+ if (browser) {
306
+ try {
307
+ await (await browser).context.close();
308
+ }
309
+ catch { /* A crashed browser is already closed. */ }
310
+ }
311
+ resolveClosed();
312
+ })();
313
+ return closePromise;
314
+ };
315
+ function scheduleIdle() {
316
+ if (stopping || clients.size)
317
+ return;
318
+ if (idleTimer)
319
+ clearTimeout(idleTimer);
320
+ idleTimer = setTimeout(() => { void close(); }, options.idleMs ?? 5_000);
321
+ }
322
+ await new Promise((resolve, reject) => {
323
+ server.once("error", reject);
324
+ server.listen(options.socketPath, () => { server.removeListener("error", reject); resolve(); });
325
+ });
326
+ if (process.platform !== "win32")
327
+ fs.chmodSync(options.socketPath, 0o600);
328
+ scheduleIdle();
329
+ return { close, closed };
330
+ }
331
+ //# sourceMappingURL=turn-broker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"turn-broker.js","sourceRoot":"","sources":["../../src/core/turn-broker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /** One executing turn per profile; idle conversations never hold the queue. */
2
+ export declare class TurnQueue {
3
+ private pending;
4
+ private active;
5
+ run<T>(run: () => Promise<T>, options?: {
6
+ signal?: AbortSignal;
7
+ onPosition?: (position: number) => void;
8
+ }): Promise<T>;
9
+ private notify;
10
+ private position;
11
+ private drain;
12
+ }