@love-moon/chat-web 0.3.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 (77) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/cli.d.ts +2 -0
  3. package/dist/cli.js +142 -0
  4. package/dist/cli.js.map +1 -0
  5. package/dist/commands/doctor.d.ts +27 -0
  6. package/dist/commands/doctor.js +116 -0
  7. package/dist/commands/doctor.js.map +1 -0
  8. package/dist/commands/index.d.ts +3 -0
  9. package/dist/commands/index.js +4 -0
  10. package/dist/commands/index.js.map +1 -0
  11. package/dist/commands/info.d.ts +32 -0
  12. package/dist/commands/info.js +81 -0
  13. package/dist/commands/info.js.map +1 -0
  14. package/dist/commands/login.d.ts +19 -0
  15. package/dist/commands/login.js +61 -0
  16. package/dist/commands/login.js.map +1 -0
  17. package/dist/core/browser.d.ts +70 -0
  18. package/dist/core/browser.js +96 -0
  19. package/dist/core/browser.js.map +1 -0
  20. package/dist/core/errors.d.ts +60 -0
  21. package/dist/core/errors.js +153 -0
  22. package/dist/core/errors.js.map +1 -0
  23. package/dist/core/install-chromium.d.ts +55 -0
  24. package/dist/core/install-chromium.js +156 -0
  25. package/dist/core/install-chromium.js.map +1 -0
  26. package/dist/core/keyboard.d.ts +39 -0
  27. package/dist/core/keyboard.js +54 -0
  28. package/dist/core/keyboard.js.map +1 -0
  29. package/dist/core/locator-score.d.ts +41 -0
  30. package/dist/core/locator-score.js +101 -0
  31. package/dist/core/locator-score.js.map +1 -0
  32. package/dist/core/logger.d.ts +10 -0
  33. package/dist/core/logger.js +38 -0
  34. package/dist/core/logger.js.map +1 -0
  35. package/dist/core/navigate.d.ts +52 -0
  36. package/dist/core/navigate.js +102 -0
  37. package/dist/core/navigate.js.map +1 -0
  38. package/dist/core/paths.d.ts +12 -0
  39. package/dist/core/paths.js +30 -0
  40. package/dist/core/paths.js.map +1 -0
  41. package/dist/core/profile-manager.d.ts +13 -0
  42. package/dist/core/profile-manager.js +44 -0
  43. package/dist/core/profile-manager.js.map +1 -0
  44. package/dist/core/provider.d.ts +64 -0
  45. package/dist/core/provider.js +31 -0
  46. package/dist/core/provider.js.map +1 -0
  47. package/dist/core/response-watcher.d.ts +35 -0
  48. package/dist/core/response-watcher.js +70 -0
  49. package/dist/core/response-watcher.js.map +1 -0
  50. package/dist/core/snapshot.d.ts +38 -0
  51. package/dist/core/snapshot.js +137 -0
  52. package/dist/core/snapshot.js.map +1 -0
  53. package/dist/core/sse-parser.d.ts +20 -0
  54. package/dist/core/sse-parser.js +49 -0
  55. package/dist/core/sse-parser.js.map +1 -0
  56. package/dist/index.d.ts +33 -0
  57. package/dist/index.js +40 -0
  58. package/dist/index.js.map +1 -0
  59. package/dist/providers/chatgpt-sse-collector.d.ts +76 -0
  60. package/dist/providers/chatgpt-sse-collector.js +298 -0
  61. package/dist/providers/chatgpt-sse-collector.js.map +1 -0
  62. package/dist/providers/chatgpt.d.ts +56 -0
  63. package/dist/providers/chatgpt.js +357 -0
  64. package/dist/providers/chatgpt.js.map +1 -0
  65. package/dist/providers/deepseek.d.ts +22 -0
  66. package/dist/providers/deepseek.js +153 -0
  67. package/dist/providers/deepseek.js.map +1 -0
  68. package/dist/providers/gemini.d.ts +102 -0
  69. package/dist/providers/gemini.js +480 -0
  70. package/dist/providers/gemini.js.map +1 -0
  71. package/dist/providers/index.d.ts +8 -0
  72. package/dist/providers/index.js +17 -0
  73. package/dist/providers/index.js.map +1 -0
  74. package/dist/session.d.ts +121 -0
  75. package/dist/session.js +242 -0
  76. package/dist/session.js.map +1 -0
  77. package/package.json +47 -0
@@ -0,0 +1,242 @@
1
+ import { launchProviderBrowser } from "./core/browser.js";
2
+ import { NotLoggedInError } from "./core/errors.js";
3
+ import { defaultLogger } from "./core/logger.js";
4
+ import { getProvider, } from "./core/provider.js";
5
+ import { takeSnapshot } from "./core/snapshot.js";
6
+ /**
7
+ * A long-lived chat session bound to one provider account.
8
+ *
9
+ * Think of it as "the thing you'd get if you opened ChatGPT in a browser
10
+ * tab and kept it open" — same persistent profile, same Chromium context,
11
+ * same conversation memory. Multi-turn dialogue happens by calling
12
+ * `session.send()` repeatedly. `session.newChat()` starts a fresh
13
+ * conversation but keeps the browser alive.
14
+ *
15
+ * RFC §19.2: a single account must not be hit concurrently. We enforce
16
+ * this by serialising `send` / `newChat` through an internal FIFO queue,
17
+ * so callers can safely fire-and-await from multiple async paths.
18
+ */
19
+ export class ChatSession {
20
+ providerImpl;
21
+ context;
22
+ pageImpl;
23
+ userDataDir;
24
+ logger;
25
+ /** Open and return a ready-to-use session. */
26
+ static async open(providerName, options = {}) {
27
+ const logger = options.logger ?? defaultLogger;
28
+ const provider = getProvider(providerName);
29
+ const { context, page, userDataDir } = await launchProviderBrowser(providerName, {
30
+ headless: options.headless,
31
+ ...options.launch,
32
+ });
33
+ const session = new ChatSession(provider, context, page, userDataDir, logger);
34
+ try {
35
+ if (options.autoOpen !== false) {
36
+ await provider.open(page);
37
+ }
38
+ }
39
+ catch (err) {
40
+ // Don't leak the browser if open() throws.
41
+ await context.close().catch(() => undefined);
42
+ throw err;
43
+ }
44
+ return session;
45
+ }
46
+ /**
47
+ * Build a session around an already-launched browser context. Mostly
48
+ * used by tests / advanced callers that manage the browser themselves;
49
+ * regular code should go through `ChatSession.open()`.
50
+ */
51
+ static fromBrowser(args) {
52
+ return new ChatSession(args.provider, args.context, args.page, args.userDataDir, args.logger ?? defaultLogger);
53
+ }
54
+ turnCounter = 0;
55
+ queue = Promise.resolve();
56
+ closed = false;
57
+ /** Provider-side conversation id (e.g. ChatGPT `/c/{uuid}`), set after the first turn lands. */
58
+ providerConversationId;
59
+ constructor(providerImpl, context, pageImpl, userDataDir, logger) {
60
+ this.providerImpl = providerImpl;
61
+ this.context = context;
62
+ this.pageImpl = pageImpl;
63
+ this.userDataDir = userDataDir;
64
+ this.logger = logger;
65
+ }
66
+ get provider() {
67
+ return this.providerImpl.name;
68
+ }
69
+ get page() {
70
+ return this.pageImpl;
71
+ }
72
+ get turns() {
73
+ return this.turnCounter;
74
+ }
75
+ get isClosed() {
76
+ return this.closed;
77
+ }
78
+ /** Quick check: is the provider profile signed in? */
79
+ async isLoggedIn() {
80
+ this.assertOpen();
81
+ return this.providerImpl.isLoggedIn(this.pageImpl);
82
+ }
83
+ /**
84
+ * Send one message and await the assistant's full reply.
85
+ *
86
+ * Calls are serialised per session — overlapping `send`s from different
87
+ * callers won't trample each other; they queue up and run in order.
88
+ */
89
+ async send(message, options = {}) {
90
+ this.assertOpen();
91
+ return this.enqueue(async () => {
92
+ const started = Date.now();
93
+ const loggedIn = await this.providerImpl.isLoggedIn(this.pageImpl);
94
+ if (!loggedIn) {
95
+ throw new NotLoggedInError(this.providerImpl.name);
96
+ }
97
+ if (options.newChat && this.providerImpl.newChat) {
98
+ this.logger.debug(`[${this.providerImpl.name}] starting fresh chat before send`);
99
+ await this.providerImpl.newChat(this.pageImpl);
100
+ await this.providerImpl.open(this.pageImpl);
101
+ }
102
+ this.logger.debug(`[${this.providerImpl.name}] turn ${this.turnCounter}: ${truncate(message)}`);
103
+ await this.providerImpl.sendMessage(this.pageImpl, message);
104
+ const response = await this.providerImpl.waitForResponse(this.pageImpl, {
105
+ timeoutMs: options.timeoutMs,
106
+ stableMs: options.stableMs,
107
+ signal: options.signal,
108
+ onProgress: options.onProgress,
109
+ });
110
+ const turnIndex = this.turnCounter;
111
+ this.turnCounter += 1;
112
+ // Capture the provider-side conversation id (e.g. ChatGPT's
113
+ // /c/{uuid}). The URL is navigated by the provider *during* the
114
+ // reply, so we read it after waitForResponse settles. We also
115
+ // remember it on the session for cross-turn access and emit a
116
+ // session-info update so listeners (ai-sdk) see the change.
117
+ const conversationId = this.captureConversationId();
118
+ return {
119
+ turnIndex,
120
+ message,
121
+ response,
122
+ durationMs: Date.now() - started,
123
+ conversationId,
124
+ };
125
+ });
126
+ }
127
+ /**
128
+ * Provider-side conversation id (e.g. ChatGPT's /c/{uuid}). `undefined`
129
+ * before the first turn has landed, then stable for the rest of this
130
+ * `ChatSession` unless `newChat()` is called.
131
+ */
132
+ get conversationId() {
133
+ return this.providerConversationId;
134
+ }
135
+ /**
136
+ * Read the conversation id from the current page (provider permitting)
137
+ * and store it on the session. Idempotent — repeated calls within the
138
+ * same conversation will see the same id; the first call captures it.
139
+ */
140
+ captureConversationId() {
141
+ if (typeof this.providerImpl.getConversationId !== "function")
142
+ return undefined;
143
+ try {
144
+ const next = this.providerImpl.getConversationId(this.pageImpl) ?? undefined;
145
+ if (next && next !== this.providerConversationId) {
146
+ this.providerConversationId = next;
147
+ }
148
+ return this.providerConversationId;
149
+ }
150
+ catch {
151
+ return this.providerConversationId;
152
+ }
153
+ }
154
+ /** Start a fresh conversation while keeping the session/browser open. */
155
+ async newChat() {
156
+ this.assertOpen();
157
+ return this.enqueue(async () => {
158
+ if (!this.providerImpl.newChat) {
159
+ throw new Error(`Provider "${this.providerImpl.name}" does not implement newChat().`);
160
+ }
161
+ await this.providerImpl.newChat(this.pageImpl);
162
+ await this.providerImpl.open(this.pageImpl);
163
+ // Reset the turn counter — a new chat is a new conversation.
164
+ this.turnCounter = 0;
165
+ // A new chat means a new provider-side conversation id; clear so
166
+ // we don't leak the old UUID into the next turn's session info.
167
+ this.providerConversationId = undefined;
168
+ });
169
+ }
170
+ /** Provider-specific health probe (input found, send button found, ...). */
171
+ async diagnose() {
172
+ this.assertOpen();
173
+ return this.providerImpl.diagnose
174
+ ? this.providerImpl.diagnose(this.pageImpl)
175
+ : fallbackDiagnose(this.providerImpl, this.pageImpl);
176
+ }
177
+ /** Snapshot of interactive DOM elements (ref-based). */
178
+ async snapshot() {
179
+ this.assertOpen();
180
+ return takeSnapshot(this.pageImpl);
181
+ }
182
+ /** Close the browser context. Safe to call multiple times. */
183
+ async close() {
184
+ if (this.closed)
185
+ return;
186
+ this.closed = true;
187
+ await this.context.close().catch(() => undefined);
188
+ }
189
+ /** Enables `await using session = …` (TC39 explicit resource management). */
190
+ async [Symbol.asyncDispose]() {
191
+ await this.close();
192
+ }
193
+ assertOpen() {
194
+ if (this.closed) {
195
+ throw new Error(`ChatSession for "${this.providerImpl.name}" is already closed.`);
196
+ }
197
+ }
198
+ enqueue(task) {
199
+ // Chain on prior task; do NOT block on its failure (we don't want
200
+ // one bad message to wedge the queue forever).
201
+ const ran = this.queue.then(task, task);
202
+ this.queue = ran.then(() => undefined, () => undefined);
203
+ return ran;
204
+ }
205
+ }
206
+ /** Convenience wrapper: open → callback → close, regardless of throws. */
207
+ export async function withSession(providerName, body, options = {}) {
208
+ const session = await ChatSession.open(providerName, options);
209
+ try {
210
+ return await body(session);
211
+ }
212
+ finally {
213
+ await session.close();
214
+ }
215
+ }
216
+ async function fallbackDiagnose(provider, page) {
217
+ const [loggedIn, sendBtn] = await Promise.all([
218
+ provider.isLoggedIn(page),
219
+ provider.findSendButton(page).then((l) => l !== null).catch(() => false),
220
+ ]);
221
+ let inputFound = false;
222
+ try {
223
+ await provider.findInput(page);
224
+ inputFound = true;
225
+ }
226
+ catch {
227
+ inputFound = false;
228
+ }
229
+ return {
230
+ loggedIn,
231
+ inputFound,
232
+ sendButtonFound: sendBtn,
233
+ assistantMessageCount: 0,
234
+ stopButtonFound: false,
235
+ lastAssistantLength: 0,
236
+ pageUrl: page.url(),
237
+ };
238
+ }
239
+ function truncate(s, max = 80) {
240
+ return s.length <= max ? s : `${s.slice(0, max - 1)}…`;
241
+ }
242
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "@love-moon/chat-web",
3
+ "version": "0.3.2",
4
+ "description": "Dedicated chat-web automation runtime for ChatGPT / DeepSeek and similar web chat products.",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "git+https://github.com/lovemoon-ai/conductor.git",
8
+ "directory": "modules/chat-web"
9
+ },
10
+ "type": "module",
11
+ "main": "dist/index.js",
12
+ "types": "dist/index.d.ts",
13
+ "bin": {
14
+ "chat-web": "dist/cli.js"
15
+ },
16
+ "files": [
17
+ "dist",
18
+ "CHANGELOG.md"
19
+ ],
20
+ "publishConfig": {
21
+ "access": "public",
22
+ "provenance": true
23
+ },
24
+ "scripts": {
25
+ "build": "tsc -p tsconfig.json",
26
+ "typecheck": "tsc --noEmit -p tsconfig.json",
27
+ "clean": "rimraf dist",
28
+ "dev": "tsx src/cli.ts",
29
+ "start": "node dist/cli.js",
30
+ "test": "vitest run",
31
+ "test:watch": "vitest",
32
+ "prepublishOnly": "npm run build"
33
+ },
34
+ "engines": {
35
+ "node": ">=18"
36
+ },
37
+ "dependencies": {
38
+ "playwright": "^1.48.0"
39
+ },
40
+ "devDependencies": {
41
+ "@types/node": "^22.10.2",
42
+ "rimraf": "^5.0.10",
43
+ "tsx": "^4.19.2",
44
+ "typescript": "^5.6.3",
45
+ "vitest": "^2.1.4"
46
+ }
47
+ }