@youdie006/prodex 0.19.1 → 0.19.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.
- package/dist/chatgpt-browser.js +68 -9
- package/package.json +1 -1
package/dist/chatgpt-browser.js
CHANGED
|
@@ -1729,7 +1729,7 @@ export async function sendChatGptPrompt(options) {
|
|
|
1729
1729
|
// into; a --project/--project-new hop lands on a page with its own counts.
|
|
1730
1730
|
beforeSubmit = await evaluateOnPage(page, answerExpression());
|
|
1731
1731
|
dbgSend(`baseline url=${beforeSubmit.url} user=${beforeSubmit.userMessageCount} assistant=${beforeSubmit.assistantMessageCount}`);
|
|
1732
|
-
await insertComposerTextViaCdp(cdp, options.prompt);
|
|
1732
|
+
await insertComposerTextViaCdp(cdp, options.prompt, page);
|
|
1733
1733
|
// The send button renders asynchronously after the prompt lands. Poll for it
|
|
1734
1734
|
// BEFORE submitting so (a) submitButtonFound reflects whether the control
|
|
1735
1735
|
// actually EXISTS - otherwise a successful Enter-key submit skips the fallback
|
|
@@ -2263,6 +2263,36 @@ export function prepareComposerExpression() {
|
|
|
2263
2263
|
// just that it is non-empty): a failed clear would leave stale text prepended,
|
|
2264
2264
|
// silently submitting a contaminated prompt. Whitespace is collapsed on both
|
|
2265
2265
|
// sides because ProseMirror round-trips newlines as extra blank lines.
|
|
2266
|
+
/**
|
|
2267
|
+
* Insert the whole prompt with ONE in-page execCommand("insertText"). The
|
|
2268
|
+
* editor applies it as a single input event, so - unlike a chunked
|
|
2269
|
+
* Input.insertText sequence - nothing can interleave at a boundary and the
|
|
2270
|
+
* text lands byte-for-byte. Used for prompts too large to push through
|
|
2271
|
+
* Input.insertText in one CDP command.
|
|
2272
|
+
*/
|
|
2273
|
+
export function insertComposerTextInPageExpression(text) {
|
|
2274
|
+
const textJson = JSON.stringify(text);
|
|
2275
|
+
return `(() => {
|
|
2276
|
+
${composerExpressionHelpers()}
|
|
2277
|
+
const el = findChatGptComposerCandidate();
|
|
2278
|
+
if (!el) return { ok: false, reason: "No visible composer" };
|
|
2279
|
+
el.focus();
|
|
2280
|
+
if ("value" in el) {
|
|
2281
|
+
el.value = ${textJson};
|
|
2282
|
+
el.dispatchEvent(new Event("input", { bubbles: true }));
|
|
2283
|
+
return { ok: true };
|
|
2284
|
+
}
|
|
2285
|
+
const selection = window.getSelection();
|
|
2286
|
+
const all = document.createRange();
|
|
2287
|
+
all.selectNodeContents(el);
|
|
2288
|
+
selection.removeAllRanges();
|
|
2289
|
+
selection.addRange(all);
|
|
2290
|
+
document.execCommand("delete");
|
|
2291
|
+
const inserted = document.execCommand("insertText", false, ${textJson});
|
|
2292
|
+
if (!inserted) return { ok: false, reason: "The ChatGPT composer refused the prompt text" };
|
|
2293
|
+
return { ok: true };
|
|
2294
|
+
})()`;
|
|
2295
|
+
}
|
|
2266
2296
|
export function composerTextStateExpression(expectedText) {
|
|
2267
2297
|
const expectedJson = JSON.stringify(expectedText ?? null);
|
|
2268
2298
|
return `(() => {
|
|
@@ -2283,7 +2313,7 @@ export function composerTextStateExpression(expectedText) {
|
|
|
2283
2313
|
// Focus the composer, clear any leftover text submit-safely, type the prompt
|
|
2284
2314
|
// with native CDP input so ProseMirror registers it, then verify the composer
|
|
2285
2315
|
// holds exactly the prompt.
|
|
2286
|
-
async function insertComposerTextViaCdp(cdp, text) {
|
|
2316
|
+
async function insertComposerTextViaCdp(cdp, text, page) {
|
|
2287
2317
|
const prepared = await cdp.evaluate(prepareComposerExpression());
|
|
2288
2318
|
if (!prepared.ok)
|
|
2289
2319
|
throw new Error(prepared.reason ?? "Could not focus the ChatGPT composer");
|
|
@@ -2299,13 +2329,42 @@ async function insertComposerTextViaCdp(cdp, text) {
|
|
|
2299
2329
|
await cdp.send("Input.dispatchKeyEvent", { type: "keyUp", key: "Backspace", code: "Backspace", windowsVirtualKeyCode: 8 });
|
|
2300
2330
|
await sleep(100);
|
|
2301
2331
|
}
|
|
2302
|
-
//
|
|
2303
|
-
//
|
|
2304
|
-
//
|
|
2305
|
-
//
|
|
2306
|
-
//
|
|
2307
|
-
|
|
2308
|
-
|
|
2332
|
+
// Insertion path, chosen by size:
|
|
2333
|
+
//
|
|
2334
|
+
// Short prompts go through Input.insertText - real key-level input events,
|
|
2335
|
+
// which is what ChatGPT's composer is built for.
|
|
2336
|
+
//
|
|
2337
|
+
// Long prompts do NOT. One giant insertText stalls ProseMirror past the CDP
|
|
2338
|
+
// command timeout, and splitting it into chunks corrupts the text at the
|
|
2339
|
+
// chunk boundaries: measured live on a 95 KB prompt, the composer ended up
|
|
2340
|
+
// the right LENGTH but with content shifted from the first boundary on
|
|
2341
|
+
// (first divergence at 3,938 chars with a 4,000-char chunk size), which is
|
|
2342
|
+
// what surfaced to users as "Composer text did not match after insertion".
|
|
2343
|
+
// Both failures come from crossing the CDP boundary mid-edit, so large text
|
|
2344
|
+
// is inserted by a single in-page execCommand instead: the editor applies it
|
|
2345
|
+
// as one input event and nothing can interleave. Measured: 67 KB inserted in
|
|
2346
|
+
// ~20s, verified byte-for-byte.
|
|
2347
|
+
if (text.length <= COMPOSER_INSERT_CHUNK_CHARS) {
|
|
2348
|
+
await cdp.send("Input.insertText", { text });
|
|
2349
|
+
}
|
|
2350
|
+
else {
|
|
2351
|
+
// A 67 KB insert measured ~20s in the page, which the default 20s CDP
|
|
2352
|
+
// command budget would cut off, so this one call gets its own connection
|
|
2353
|
+
// with a size-scaled budget instead of loosening the budget for every
|
|
2354
|
+
// command on the shared connection.
|
|
2355
|
+
const budgetMs = Math.max(60_000, Math.ceil(text.length / 1_000) * 1_000);
|
|
2356
|
+
const slowCdp = page ? await connectCdp(page.webSocketDebuggerUrl, budgetMs) : undefined;
|
|
2357
|
+
try {
|
|
2358
|
+
const target = slowCdp ?? cdp;
|
|
2359
|
+
if (slowCdp)
|
|
2360
|
+
await slowCdp.send("Runtime.enable");
|
|
2361
|
+
const inserted = await target.evaluate(insertComposerTextInPageExpression(text));
|
|
2362
|
+
if (!inserted?.ok)
|
|
2363
|
+
throw new Error(inserted?.reason ?? "Could not insert the prompt into the ChatGPT composer");
|
|
2364
|
+
}
|
|
2365
|
+
finally {
|
|
2366
|
+
slowCdp?.close();
|
|
2367
|
+
}
|
|
2309
2368
|
}
|
|
2310
2369
|
await sleep(200);
|
|
2311
2370
|
const state = await cdp.evaluate(composerTextStateExpression(text));
|