@agentrhq/webcmd 0.2.5 → 0.3.1
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/README.md +13 -2
- package/cli-manifest.json +217 -13
- package/clis/_shared/site-auth.js +3 -3
- package/clis/_shared/site-auth.test.js +4 -4
- package/clis/chatgpt/ask.js +1 -1
- package/clis/chatgpt/ask.test.js +11 -0
- package/clis/chatgpt/commands.test.js +102 -1
- package/clis/chatgpt/deep-research-result.js +45 -3
- package/clis/chatgpt/image.js +22 -2
- package/clis/chatgpt/project-file-add.js +24 -1
- package/clis/chatgpt/utils.js +258 -52
- package/clis/chatgpt/utils.test.js +259 -1
- package/clis/claude/ask.js +21 -1
- package/clis/facebook/feed.js +110 -24
- package/clis/facebook/feed.test.js +62 -0
- package/clis/facebook/search.js +185 -38
- package/clis/facebook/search.test.js +95 -50
- package/clis/instagram/explore.js +30 -12
- package/clis/instagram/explore.test.js +77 -0
- package/clis/instagram/post.js +14 -1
- package/clis/instagram/reel.js +13 -1
- package/clis/linkedin/company.js +153 -0
- package/clis/linkedin/company.test.js +111 -0
- package/clis/linkedin/connections.js +135 -0
- package/clis/linkedin/connections.test.js +141 -0
- package/clis/mercury/reimbursement-draft.js +12 -1
- package/clis/slock/whoami.test.js +2 -2
- package/clis/twitter/article-evaluate.test.js +27 -0
- package/clis/twitter/article.js +73 -16
- package/clis/twitter/article.test.js +209 -0
- package/clis/twitter/download.js +6 -1
- package/clis/twitter/post.js +14 -1
- package/clis/twitter/profile.js +1 -1
- package/clis/twitter/profile.test.js +8 -0
- package/clis/twitter/quote.js +11 -1
- package/clis/twitter/reply.js +11 -1
- package/dist/src/browser/base-page.d.ts +26 -0
- package/dist/src/browser/base-page.js +23 -8
- package/dist/src/browser/base-page.test.js +45 -12
- package/dist/src/browser/command-catalog.d.ts +6 -0
- package/dist/src/browser/command-catalog.js +259 -0
- package/dist/src/browser/command-catalog.test.d.ts +1 -0
- package/dist/src/browser/command-catalog.test.js +79 -0
- package/dist/src/browser/daemon-client.d.ts +2 -1
- package/dist/src/browser/runtime/local-cloak/actions.js +4 -1
- package/dist/src/browser/runtime/local-cloak/darwin-background-launch.d.ts +17 -0
- package/dist/src/browser/runtime/local-cloak/darwin-background-launch.js +106 -0
- package/dist/src/browser/runtime/local-cloak/darwin-background-launch.test.d.ts +1 -0
- package/dist/src/browser/runtime/local-cloak/darwin-background-launch.test.js +65 -0
- package/dist/src/browser/runtime/local-cloak/provider.test.js +36 -0
- package/dist/src/browser/runtime/local-cloak/session-manager.d.ts +10 -2
- package/dist/src/browser/runtime/local-cloak/session-manager.js +25 -9
- package/dist/src/browser/runtime/local-cloak/session-manager.test.js +36 -0
- package/dist/src/browser/target-resolver.d.ts +1 -0
- package/dist/src/browser/target-resolver.js +99 -4
- package/dist/src/browser/target-resolver.test.js +141 -1
- package/dist/src/build-manifest.d.ts +6 -0
- package/dist/src/build-manifest.js +18 -1
- package/dist/src/build-manifest.test.js +57 -1
- package/dist/src/builtin-command-surface.d.ts +9 -0
- package/dist/src/builtin-command-surface.js +16 -0
- package/dist/src/check-hosted-contract.test.d.ts +1 -0
- package/dist/src/check-hosted-contract.test.js +56 -0
- package/dist/src/cli.js +63 -110
- package/dist/src/cli.test.js +82 -6
- package/dist/src/command-presentation.d.ts +95 -0
- package/dist/src/command-presentation.js +486 -0
- package/dist/src/command-presentation.test.d.ts +1 -0
- package/dist/src/command-presentation.test.js +97 -0
- package/dist/src/command-surface.d.ts +43 -0
- package/dist/src/command-surface.js +205 -0
- package/dist/src/command-surface.test.d.ts +1 -0
- package/dist/src/command-surface.test.js +406 -0
- package/dist/src/commanderAdapter.d.ts +5 -1
- package/dist/src/commanderAdapter.js +12 -55
- package/dist/src/commanderAdapter.test.js +15 -3
- package/dist/src/commands/auth.js +3 -2
- package/dist/src/commands/auth.test.js +6 -6
- package/dist/src/community-plugin-sync.d.ts +11 -0
- package/dist/src/community-plugin-sync.js +138 -0
- package/dist/src/community-plugin-sync.test.d.ts +1 -0
- package/dist/src/community-plugin-sync.test.js +123 -0
- package/dist/src/completion-fast.d.ts +4 -4
- package/dist/src/completion-fast.js +15 -34
- package/dist/src/completion-shared.d.ts +4 -0
- package/dist/src/completion-shared.js +38 -0
- package/dist/src/completion.js +3 -27
- package/dist/src/completion.test.js +31 -2
- package/dist/src/docs-sync-review-cli.test.d.ts +1 -0
- package/dist/src/docs-sync-review-cli.test.js +322 -0
- package/dist/src/docs-sync-review.d.ts +117 -0
- package/dist/src/docs-sync-review.js +475 -0
- package/dist/src/docs-sync-review.test.d.ts +1 -0
- package/dist/src/docs-sync-review.test.js +324 -0
- package/dist/src/errors.d.ts +12 -3
- package/dist/src/errors.js +11 -7
- package/dist/src/errors.test.js +14 -1
- package/dist/src/execution.d.ts +1 -2
- package/dist/src/execution.js +4 -45
- package/dist/src/generate-release-notes-cli.test.js +11 -1
- package/dist/src/help.d.ts +4 -0
- package/dist/src/help.js +50 -255
- package/dist/src/help.test.js +27 -1
- package/dist/src/hosted/args.d.ts +4 -0
- package/dist/src/hosted/args.js +4 -0
- package/dist/src/hosted/args.test.d.ts +1 -0
- package/dist/src/hosted/args.test.js +49 -0
- package/dist/src/hosted/availability.d.ts +13 -0
- package/dist/src/hosted/availability.js +16 -0
- package/dist/src/hosted/availability.test.d.ts +1 -0
- package/dist/src/hosted/availability.test.js +180 -0
- package/dist/src/hosted/browser-args.d.ts +18 -0
- package/dist/src/hosted/browser-args.js +152 -0
- package/dist/src/hosted/browser-args.test.d.ts +1 -0
- package/dist/src/hosted/browser-args.test.js +182 -0
- package/dist/src/hosted/client.d.ts +59 -0
- package/dist/src/hosted/client.js +510 -0
- package/dist/src/hosted/client.test.d.ts +1 -0
- package/dist/src/hosted/client.test.js +738 -0
- package/dist/src/hosted/config.d.ts +55 -0
- package/dist/src/hosted/config.js +112 -0
- package/dist/src/hosted/config.test.d.ts +1 -0
- package/dist/src/hosted/config.test.js +81 -0
- package/dist/src/hosted/contract.d.ts +94 -0
- package/dist/src/hosted/contract.js +208 -0
- package/dist/src/hosted/contract.test.d.ts +1 -0
- package/dist/src/hosted/contract.test.js +361 -0
- package/dist/src/hosted/credentials.d.ts +38 -0
- package/dist/src/hosted/credentials.js +248 -0
- package/dist/src/hosted/credentials.test.d.ts +1 -0
- package/dist/src/hosted/credentials.test.js +93 -0
- package/dist/src/hosted/file-contract.test.d.ts +1 -0
- package/dist/src/hosted/file-contract.test.js +174 -0
- package/dist/src/hosted/files.d.ts +29 -0
- package/dist/src/hosted/files.js +296 -0
- package/dist/src/hosted/files.test.d.ts +1 -0
- package/dist/src/hosted/files.test.js +231 -0
- package/dist/src/hosted/main-lifecycle.test.d.ts +1 -0
- package/dist/src/hosted/main-lifecycle.test.js +213 -0
- package/dist/src/hosted/manifest.d.ts +14 -0
- package/dist/src/hosted/manifest.js +47 -0
- package/dist/src/hosted/manifest.test.d.ts +1 -0
- package/dist/src/hosted/manifest.test.js +164 -0
- package/dist/src/hosted/output-parity.test.d.ts +1 -0
- package/dist/src/hosted/output-parity.test.js +108 -0
- package/dist/src/hosted/root-command-surface.test.d.ts +1 -0
- package/dist/src/hosted/root-command-surface.test.js +646 -0
- package/dist/src/hosted/runner.d.ts +19 -0
- package/dist/src/hosted/runner.js +705 -0
- package/dist/src/hosted/runner.test.d.ts +1 -0
- package/dist/src/hosted/runner.test.js +1607 -0
- package/dist/src/hosted/setup.d.ts +10 -0
- package/dist/src/hosted/setup.js +79 -0
- package/dist/src/hosted/setup.test.d.ts +1 -0
- package/dist/src/hosted/setup.test.js +195 -0
- package/dist/src/hosted/types.d.ts +175 -0
- package/dist/src/hosted/types.js +1 -0
- package/dist/src/main.js +123 -97
- package/dist/src/manifest-types.d.ts +2 -0
- package/dist/src/output.d.ts +17 -2
- package/dist/src/output.js +88 -81
- package/dist/src/output.test.js +141 -51
- package/dist/src/pipeline/executor.test.js +1 -0
- package/dist/src/pipeline/steps/download.test.js +1 -0
- package/dist/src/plugin-create-cli.test.d.ts +1 -0
- package/dist/src/plugin-create-cli.test.js +37 -0
- package/dist/src/plugin-manifest.d.ts +12 -0
- package/dist/src/plugin-manifest.js +16 -0
- package/dist/src/plugin-manifest.test.js +19 -1
- package/dist/src/plugin-scaffold.d.ts +4 -1
- package/dist/src/plugin-scaffold.js +4 -1
- package/dist/src/plugin-scaffold.test.js +23 -8
- package/dist/src/plugin.js +4 -1
- package/dist/src/plugin.test.js +13 -0
- package/dist/src/registry.d.ts +2 -0
- package/dist/src/release-notes.d.ts +6 -1
- package/dist/src/release-notes.js +192 -4
- package/dist/src/release-notes.test.js +143 -4
- package/dist/src/root-command-surface.d.ts +31 -0
- package/dist/src/root-command-surface.js +106 -0
- package/dist/src/serialization.d.ts +1 -16
- package/dist/src/serialization.js +5 -55
- package/dist/src/stream-write.d.ts +12 -0
- package/dist/src/stream-write.js +91 -0
- package/dist/src/stream-write.test.d.ts +1 -0
- package/dist/src/stream-write.test.js +186 -0
- package/dist/src/types.d.ts +5 -0
- package/dist/src/utils.d.ts +1 -1
- package/dist/src/utils.js +2 -8
- package/dist/src/utils.test.js +50 -0
- package/hosted-contract.json +36748 -0
- package/package.json +6 -1
- package/scripts/check-hosted-contract.mjs +108 -0
- package/scripts/docs-sync-review.ts +332 -0
- package/scripts/generate-release-notes.ts +1 -1
- package/scripts/sync-community-plugins.ts +14 -0
- package/skills/smart-search/SKILL.md +14 -3
- package/skills/webcmd-autofix/SKILL.md +26 -37
- package/skills/webcmd-usage/SKILL.md +21 -7
- package/clis/antigravity/SKILL.md +0 -38
|
@@ -28,7 +28,30 @@ export const projectFileAddCommand = cli({
|
|
|
28
28
|
siteSession: 'persistent',
|
|
29
29
|
navigateBefore: false,
|
|
30
30
|
args: [
|
|
31
|
-
{
|
|
31
|
+
{
|
|
32
|
+
name: 'file',
|
|
33
|
+
positional: true,
|
|
34
|
+
required: true,
|
|
35
|
+
help: 'Local file path(s) to upload; comma-separated paths are supported',
|
|
36
|
+
file: {
|
|
37
|
+
direction: 'input',
|
|
38
|
+
pathKind: 'file',
|
|
39
|
+
multiple: true,
|
|
40
|
+
separator: ',',
|
|
41
|
+
contentTypes: [
|
|
42
|
+
'application/pdf',
|
|
43
|
+
'text/plain',
|
|
44
|
+
'text/markdown',
|
|
45
|
+
'text/csv',
|
|
46
|
+
'application/json',
|
|
47
|
+
'image/jpeg',
|
|
48
|
+
'image/png',
|
|
49
|
+
'image/gif',
|
|
50
|
+
'image/webp',
|
|
51
|
+
],
|
|
52
|
+
maxBytes: 26_214_400,
|
|
53
|
+
},
|
|
54
|
+
},
|
|
32
55
|
{ name: 'id', required: true, help: 'Project ID or /g/g-p-<id> URL' },
|
|
33
56
|
],
|
|
34
57
|
columns: ['Status', 'File'],
|
package/clis/chatgpt/utils.js
CHANGED
|
@@ -1059,8 +1059,10 @@ export async function sendChatGPTMessage(page, text) {
|
|
|
1059
1059
|
return true;
|
|
1060
1060
|
}
|
|
1061
1061
|
|
|
1062
|
-
export async function getVisibleMessages(page) {
|
|
1062
|
+
export async function getVisibleMessages(page, { textOnly = false } = {}) {
|
|
1063
|
+
const includeHtml = textOnly ? 'false' : 'true';
|
|
1063
1064
|
const result = requireArrayEvaluateResult(unwrapEvaluateResult(await page.evaluate(`(() => {
|
|
1065
|
+
const includeHtml = ${includeHtml};
|
|
1064
1066
|
const isVisible = (el) => {
|
|
1065
1067
|
if (!(el instanceof HTMLElement)) return false;
|
|
1066
1068
|
const style = window.getComputedStyle(el);
|
|
@@ -1097,8 +1099,11 @@ export async function getVisibleMessages(page) {
|
|
|
1097
1099
|
|| node.querySelector('.markdown')
|
|
1098
1100
|
|| node.querySelector('[data-message-author-role]')
|
|
1099
1101
|
|| node;
|
|
1100
|
-
const html = contentNode instanceof HTMLElement ? (contentNode.innerHTML || '') : '';
|
|
1101
|
-
const
|
|
1102
|
+
const html = includeHtml && contentNode instanceof HTMLElement ? (contentNode.innerHTML || '') : '';
|
|
1103
|
+
const rawText = contentNode instanceof HTMLElement
|
|
1104
|
+
? (includeHtml ? (contentNode.innerText || contentNode.textContent || '') : (contentNode.textContent || ''))
|
|
1105
|
+
: '';
|
|
1106
|
+
const text = normalize(rawText);
|
|
1102
1107
|
if (!text) continue;
|
|
1103
1108
|
const key = role + '\\n' + text;
|
|
1104
1109
|
if (seen.has(key)) continue;
|
|
@@ -1169,7 +1174,7 @@ export async function waitForChatGPTDetailRows(page, { wantMarkdown = false, tim
|
|
|
1169
1174
|
lastKey = key;
|
|
1170
1175
|
stableStartedAt = 0;
|
|
1171
1176
|
}
|
|
1172
|
-
await page.
|
|
1177
|
+
await page.sleep(3);
|
|
1173
1178
|
}
|
|
1174
1179
|
|
|
1175
1180
|
throw new TimeoutError(
|
|
@@ -1255,25 +1260,171 @@ function extractDeepResearchSourcesFromReportMessage(reportMessage) {
|
|
|
1255
1260
|
return [...byUrl.values()].slice(0, 200);
|
|
1256
1261
|
}
|
|
1257
1262
|
|
|
1258
|
-
function
|
|
1259
|
-
const
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1263
|
+
function pickFirstObject(...values) {
|
|
1264
|
+
for (const value of values) {
|
|
1265
|
+
const parsed = parseJsonMaybe(value);
|
|
1266
|
+
if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) return parsed;
|
|
1267
|
+
}
|
|
1268
|
+
return {};
|
|
1269
|
+
}
|
|
1270
|
+
|
|
1271
|
+
function stringOrEmpty(value) {
|
|
1272
|
+
return value === undefined || value === null ? '' : String(value);
|
|
1273
|
+
}
|
|
1274
|
+
|
|
1275
|
+
function compactDeepResearchPlanSteps(plan, stepStatusesByPlan) {
|
|
1276
|
+
const steps = Array.isArray(plan?.steps) ? plan.steps : [];
|
|
1277
|
+
return steps.slice(0, 50).map((step, index) => {
|
|
1278
|
+
const id = stringOrEmpty(step?.id || step?.step_id || step?.plan_step_id || step?.key || index);
|
|
1279
|
+
return {
|
|
1280
|
+
id,
|
|
1281
|
+
title: stringOrEmpty(step?.title || step?.name || step?.summary || step?.description),
|
|
1282
|
+
status: stringOrEmpty(step?.status || step?.step_status || stepStatusesByPlan?.[id] || ''),
|
|
1283
|
+
};
|
|
1284
|
+
}).filter((step) => step.id || step.title || step.status);
|
|
1285
|
+
}
|
|
1286
|
+
|
|
1287
|
+
function deepResearchProgressStatus(progress) {
|
|
1288
|
+
const venusStatus = String(progress.venusStatus || '').toLowerCase();
|
|
1289
|
+
if (/waiting_for_user|user_response/.test(venusStatus)) return 'waiting_for_user';
|
|
1290
|
+
if (/needs_user|user_action|action_required|requires_action/.test(venusStatus)) return 'needs_user_action';
|
|
1291
|
+
if (/running|in_progress|loading|generating|researching|queued|started|processing/.test(venusStatus)) return 'running';
|
|
1292
|
+
|
|
1293
|
+
const venusMessageType = String(progress.venusMessageType || '').toLowerCase();
|
|
1294
|
+
if (/loading|running|generating|research|progress/.test(venusMessageType)) return 'running';
|
|
1295
|
+
|
|
1296
|
+
if (progress.asyncTaskConversationId
|
|
1297
|
+
|| progress.widgetSessionId
|
|
1298
|
+
|| progress.asyncStatus !== undefined
|
|
1299
|
+
|| progress.venusStatus
|
|
1300
|
+
|| progress.planId
|
|
1301
|
+
|| progress.planTitle) {
|
|
1302
|
+
return 'not_ready';
|
|
1303
|
+
}
|
|
1304
|
+
return '';
|
|
1305
|
+
}
|
|
1306
|
+
|
|
1307
|
+
function buildDeepResearchProgressResult(state, responseMetadata, source) {
|
|
1308
|
+
const widgetState = state && typeof state === 'object' ? state : {};
|
|
1309
|
+
const response = responseMetadata && typeof responseMetadata === 'object' ? responseMetadata : {};
|
|
1310
|
+
const plan = pickFirstObject(widgetState.plan, widgetState.current_plan, widgetState.research_plan);
|
|
1311
|
+
const stepStatusesByPlan = pickFirstObject(
|
|
1312
|
+
widgetState.step_statuses_by_plan,
|
|
1313
|
+
widgetState.stepStatusesByPlan,
|
|
1314
|
+
widgetState.step_statuses,
|
|
1315
|
+
);
|
|
1316
|
+
const progress = {
|
|
1317
|
+
asyncTaskConversationId: stringOrEmpty(
|
|
1318
|
+
response.async_task_conversation_id
|
|
1319
|
+
|| response.asyncTaskConversationId
|
|
1320
|
+
|| response['openai/asyncTaskConversationId'],
|
|
1321
|
+
),
|
|
1322
|
+
widgetSessionId: stringOrEmpty(
|
|
1323
|
+
response['openai/widgetSessionId']
|
|
1324
|
+
|| response.widget_session_id
|
|
1325
|
+
|| response.widgetSessionId,
|
|
1326
|
+
),
|
|
1327
|
+
asyncStatus: response['openai/asyncStatus'] ?? response.async_status ?? response.asyncStatus,
|
|
1328
|
+
venusMessageType: stringOrEmpty(response.venus_message_type || response.venusMessageType),
|
|
1329
|
+
venusStatus: stringOrEmpty(widgetState.status || widgetState.venus_status || widgetState.venusStatus),
|
|
1330
|
+
waitingForUserUntil: stringOrEmpty(
|
|
1331
|
+
widgetState.waiting_for_user_response_on_plan_until
|
|
1332
|
+
|| widgetState.waitingForUserResponseOnPlanUntil
|
|
1333
|
+
|| widgetState.waiting_for_user_until,
|
|
1334
|
+
),
|
|
1335
|
+
planId: stringOrEmpty(plan.plan_id || plan.planId || plan.id),
|
|
1336
|
+
planTitle: stringOrEmpty(plan.title || plan.name),
|
|
1337
|
+
planSteps: compactDeepResearchPlanSteps(plan, stepStatusesByPlan),
|
|
1338
|
+
stepStatusesByPlan,
|
|
1339
|
+
};
|
|
1340
|
+
const status = deepResearchProgressStatus(progress);
|
|
1341
|
+
if (!status) return null;
|
|
1342
|
+
|
|
1343
|
+
if (/^completed$/i.test(progress.venusStatus)
|
|
1344
|
+
&& !progress.asyncTaskConversationId
|
|
1345
|
+
&& !progress.widgetSessionId
|
|
1346
|
+
&& progress.asyncStatus === undefined
|
|
1347
|
+
&& !progress.venusMessageType
|
|
1348
|
+
&& !progress.planId
|
|
1349
|
+
&& !progress.planTitle
|
|
1350
|
+
&& !progress.planSteps.length
|
|
1351
|
+
&& !Object.keys(progress.stepStatusesByPlan || {}).length) {
|
|
1352
|
+
return null;
|
|
1353
|
+
}
|
|
1354
|
+
|
|
1265
1355
|
return {
|
|
1266
|
-
status
|
|
1267
|
-
report,
|
|
1356
|
+
status,
|
|
1357
|
+
report: '',
|
|
1268
1358
|
html: '',
|
|
1269
|
-
method: source,
|
|
1270
|
-
sources:
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1359
|
+
method: source.includes('widget-state') ? source.replace('widget-state', 'widget-progress') : `${source}-progress`,
|
|
1360
|
+
sources: [],
|
|
1361
|
+
progress,
|
|
1362
|
+
asyncTaskConversationId: progress.asyncTaskConversationId,
|
|
1363
|
+
widgetSessionId: progress.widgetSessionId,
|
|
1364
|
+
asyncStatus: progress.asyncStatus,
|
|
1365
|
+
venusMessageType: progress.venusMessageType,
|
|
1366
|
+
venusStatus: progress.venusStatus,
|
|
1367
|
+
waitingForUserUntil: progress.waitingForUserUntil,
|
|
1368
|
+
planId: progress.planId,
|
|
1369
|
+
planTitle: progress.planTitle,
|
|
1274
1370
|
};
|
|
1275
1371
|
}
|
|
1276
1372
|
|
|
1373
|
+
function deepResearchCandidateScore(candidate) {
|
|
1374
|
+
if (!candidate) return 0;
|
|
1375
|
+
if (candidate.status === 'completed') return 1000000 + (candidate.reportLength || candidate.report?.length || 0);
|
|
1376
|
+
if (candidate.status === 'waiting_for_user' || candidate.status === 'needs_user_action') return 500000;
|
|
1377
|
+
if (candidate.status === 'running') return 400000;
|
|
1378
|
+
if (candidate.status === 'not_ready') return 300000;
|
|
1379
|
+
return 1;
|
|
1380
|
+
}
|
|
1381
|
+
|
|
1382
|
+
function selectDeepResearchCandidate(candidates, payload, mapping) {
|
|
1383
|
+
if (!candidates.length) return null;
|
|
1384
|
+
const lineage = new Set();
|
|
1385
|
+
let nodeId = String(payload.current_node || payload.currentNode || '');
|
|
1386
|
+
while (nodeId && !lineage.has(nodeId)) {
|
|
1387
|
+
lineage.add(nodeId);
|
|
1388
|
+
nodeId = String(mapping[nodeId]?.parent || '');
|
|
1389
|
+
}
|
|
1390
|
+
const currentBranch = lineage.size
|
|
1391
|
+
? candidates.filter((candidate) => lineage.has(candidate.conversationMessageId))
|
|
1392
|
+
: [];
|
|
1393
|
+
const pool = currentBranch.length ? currentBranch : candidates;
|
|
1394
|
+
pool.sort((a, b) => {
|
|
1395
|
+
const createdDelta = b._createdAt - a._createdAt;
|
|
1396
|
+
if (createdDelta) return createdDelta;
|
|
1397
|
+
const orderDelta = b._candidateOrder - a._candidateOrder;
|
|
1398
|
+
if (currentBranch.length && orderDelta) return orderDelta;
|
|
1399
|
+
const scoreDelta = deepResearchCandidateScore(b) - deepResearchCandidateScore(a);
|
|
1400
|
+
return scoreDelta || orderDelta;
|
|
1401
|
+
});
|
|
1402
|
+
const { _createdAt, _candidateOrder, ...selected } = pool[0];
|
|
1403
|
+
return selected;
|
|
1404
|
+
}
|
|
1405
|
+
|
|
1406
|
+
function extractDeepResearchFromWidgetState(widgetState, source = 'conversation-widget-state', responseMetadata = null) {
|
|
1407
|
+
const state = parseJsonMaybe(widgetState);
|
|
1408
|
+
if ((!state || typeof state !== 'object') && !responseMetadata) return null;
|
|
1409
|
+
const widgetStateObject = state && typeof state === 'object' ? state : {};
|
|
1410
|
+
const reportMessage = widgetStateObject.report_message || widgetStateObject.reportMessage || null;
|
|
1411
|
+
const parts = Array.isArray(reportMessage?.content?.parts) ? reportMessage.content.parts : [];
|
|
1412
|
+
const report = normalizeDeepResearchText(parts.filter((part) => typeof part === 'string').join('\n\n'));
|
|
1413
|
+
if (looksLikeDeepResearchReport(report)) {
|
|
1414
|
+
return {
|
|
1415
|
+
status: 'completed',
|
|
1416
|
+
report,
|
|
1417
|
+
html: '',
|
|
1418
|
+
method: source,
|
|
1419
|
+
sources: extractDeepResearchSourcesFromReportMessage(reportMessage),
|
|
1420
|
+
widgetStatus: String(widgetStateObject.status || ''),
|
|
1421
|
+
reportMessageId: String(reportMessage?.id || ''),
|
|
1422
|
+
reportLength: report.length,
|
|
1423
|
+
};
|
|
1424
|
+
}
|
|
1425
|
+
return buildDeepResearchProgressResult(widgetStateObject, pickFirstObject(responseMetadata), source);
|
|
1426
|
+
}
|
|
1427
|
+
|
|
1277
1428
|
function extractDeepResearchFromConversationPayload(payload, { expectedConversationId = '' } = {}) {
|
|
1278
1429
|
if (!payload || typeof payload !== 'object' || Array.isArray(payload)) {
|
|
1279
1430
|
throw new CommandExecutionError('Malformed ChatGPT conversation payload for Deep Research extraction.');
|
|
@@ -1291,24 +1442,33 @@ function extractDeepResearchFromConversationPayload(payload, { expectedConversat
|
|
|
1291
1442
|
const candidates = [];
|
|
1292
1443
|
for (const [messageId, node] of Object.entries(mapping)) {
|
|
1293
1444
|
const message = node?.message || {};
|
|
1294
|
-
const
|
|
1445
|
+
const metadata = message?.metadata || {};
|
|
1446
|
+
const sdk = metadata?.chatgpt_sdk || {};
|
|
1447
|
+
const responseMetadata = pickFirstObject(
|
|
1448
|
+
sdk?.response_metadata,
|
|
1449
|
+
sdk?.responseMetadata,
|
|
1450
|
+
metadata?.response_metadata,
|
|
1451
|
+
metadata?.responseMetadata,
|
|
1452
|
+
);
|
|
1295
1453
|
for (const widgetState of [
|
|
1296
1454
|
sdk?.widget_state,
|
|
1297
1455
|
sdk?.widgetState,
|
|
1298
|
-
|
|
1299
|
-
|
|
1456
|
+
metadata?.widget_state,
|
|
1457
|
+
metadata?.widgetState,
|
|
1300
1458
|
]) {
|
|
1301
|
-
|
|
1459
|
+
if (widgetState === undefined || widgetState === null) continue;
|
|
1460
|
+
const extracted = extractDeepResearchFromWidgetState(widgetState, 'conversation-widget-state', responseMetadata);
|
|
1302
1461
|
if (extracted) {
|
|
1303
1462
|
candidates.push({
|
|
1304
1463
|
...extracted,
|
|
1305
1464
|
conversationMessageId: messageId,
|
|
1465
|
+
_createdAt: Number(message.create_time || message.createTime || metadata.create_time || 0) || 0,
|
|
1466
|
+
_candidateOrder: candidates.length,
|
|
1306
1467
|
});
|
|
1307
1468
|
}
|
|
1308
1469
|
}
|
|
1309
1470
|
}
|
|
1310
|
-
candidates
|
|
1311
|
-
return candidates[0] || null;
|
|
1471
|
+
return selectDeepResearchCandidate(candidates, payload, mapping);
|
|
1312
1472
|
}
|
|
1313
1473
|
|
|
1314
1474
|
function conversationIdFromBackendConversationUrl(url) {
|
|
@@ -1331,12 +1491,14 @@ function extractDeepResearchFromNetworkEntries(entries, { expectedConversationId
|
|
|
1331
1491
|
if (extracted) {
|
|
1332
1492
|
candidates.push({
|
|
1333
1493
|
...extracted,
|
|
1334
|
-
method: '
|
|
1494
|
+
method: extracted.status === 'completed'
|
|
1495
|
+
? 'network-conversation-widget-state'
|
|
1496
|
+
: 'network-conversation-widget-progress',
|
|
1335
1497
|
networkUrl: url,
|
|
1336
1498
|
});
|
|
1337
1499
|
}
|
|
1338
1500
|
}
|
|
1339
|
-
candidates.sort((a, b) => b
|
|
1501
|
+
candidates.sort((a, b) => deepResearchCandidateScore(b) - deepResearchCandidateScore(a));
|
|
1340
1502
|
return candidates[0] || null;
|
|
1341
1503
|
}
|
|
1342
1504
|
|
|
@@ -1570,6 +1732,7 @@ export async function getChatGPTDeepResearchResult(page, { conversationId = '',
|
|
|
1570
1732
|
);
|
|
1571
1733
|
}
|
|
1572
1734
|
}
|
|
1735
|
+
let progressCandidate = null;
|
|
1573
1736
|
const diagnostics = {
|
|
1574
1737
|
iframeCount: Array.isArray(iframeState.iframes) ? iframeState.iframes.length : 0,
|
|
1575
1738
|
iframe: iframe ? {
|
|
@@ -1605,19 +1768,26 @@ export async function getChatGPTDeepResearchResult(page, { conversationId = '',
|
|
|
1605
1768
|
const extracted = extractDeepResearchFromNetworkEntries(relevantEntries, { expectedConversationId: conversationId });
|
|
1606
1769
|
if (extracted) {
|
|
1607
1770
|
diagnostics.networkConversation = {
|
|
1608
|
-
foundReport:
|
|
1771
|
+
foundReport: extracted.status === 'completed',
|
|
1772
|
+
foundProgress: extracted.status !== 'completed',
|
|
1773
|
+
status: extracted.status,
|
|
1609
1774
|
reportLength: extracted.reportLength || extracted.report.length,
|
|
1610
1775
|
sourceCount: Array.isArray(extracted.sources) ? extracted.sources.length : 0,
|
|
1776
|
+
venusStatus: extracted.venusStatus || '',
|
|
1777
|
+
asyncTaskConversationId: extracted.asyncTaskConversationId || '',
|
|
1611
1778
|
};
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1779
|
+
if (extracted.status === 'completed') {
|
|
1780
|
+
return {
|
|
1781
|
+
status: 'completed',
|
|
1782
|
+
report: extracted.report,
|
|
1783
|
+
html: '',
|
|
1784
|
+
url: iframeState.url,
|
|
1785
|
+
method: extracted.method,
|
|
1786
|
+
sources: extracted.sources || [],
|
|
1787
|
+
diagnostics,
|
|
1788
|
+
};
|
|
1789
|
+
}
|
|
1790
|
+
progressCandidate = extracted;
|
|
1621
1791
|
}
|
|
1622
1792
|
} catch (error) {
|
|
1623
1793
|
if (error instanceof CommandExecutionError) throw error;
|
|
@@ -1640,12 +1810,16 @@ export async function getChatGPTDeepResearchResult(page, { conversationId = '',
|
|
|
1640
1810
|
status: conversation?.status || 0,
|
|
1641
1811
|
contentType: conversation?.contentType || '',
|
|
1642
1812
|
transport: conversation?.transport || '',
|
|
1643
|
-
foundReport:
|
|
1813
|
+
foundReport: extracted?.status === 'completed',
|
|
1814
|
+
foundProgress: !!extracted && extracted.status !== 'completed',
|
|
1815
|
+
deepResearchStatus: extracted?.status || '',
|
|
1644
1816
|
reportLength: extracted?.reportLength || 0,
|
|
1645
1817
|
widgetStatus: extracted?.widgetStatus || '',
|
|
1818
|
+
venusStatus: extracted?.venusStatus || '',
|
|
1819
|
+
asyncTaskConversationId: extracted?.asyncTaskConversationId || '',
|
|
1646
1820
|
sourceCount: Array.isArray(extracted?.sources) ? extracted.sources.length : 0,
|
|
1647
1821
|
};
|
|
1648
|
-
if (extracted) {
|
|
1822
|
+
if (extracted?.status === 'completed') {
|
|
1649
1823
|
return {
|
|
1650
1824
|
status: 'completed',
|
|
1651
1825
|
report: extracted.report,
|
|
@@ -1656,6 +1830,7 @@ export async function getChatGPTDeepResearchResult(page, { conversationId = '',
|
|
|
1656
1830
|
diagnostics,
|
|
1657
1831
|
};
|
|
1658
1832
|
}
|
|
1833
|
+
if (extracted) progressCandidate = extracted;
|
|
1659
1834
|
}
|
|
1660
1835
|
} catch (error) {
|
|
1661
1836
|
if (error instanceof CommandExecutionError) throw error;
|
|
@@ -1663,6 +1838,14 @@ export async function getChatGPTDeepResearchResult(page, { conversationId = '',
|
|
|
1663
1838
|
}
|
|
1664
1839
|
}
|
|
1665
1840
|
|
|
1841
|
+
if (progressCandidate) {
|
|
1842
|
+
return {
|
|
1843
|
+
...progressCandidate,
|
|
1844
|
+
url: iframeState.url,
|
|
1845
|
+
diagnostics,
|
|
1846
|
+
};
|
|
1847
|
+
}
|
|
1848
|
+
|
|
1666
1849
|
if (iframe?.text && looksLikeDeepResearchReport(iframe.text)) {
|
|
1667
1850
|
return {
|
|
1668
1851
|
status: 'completed',
|
|
@@ -1820,8 +2003,10 @@ export async function waitForChatGPTDeepResearchResult(page, { conversationId =
|
|
|
1820
2003
|
lastReport = result.report;
|
|
1821
2004
|
stableStartedAt = Date.now();
|
|
1822
2005
|
}
|
|
2006
|
+
} else if (result.status === 'waiting_for_user' || result.status === 'needs_user_action') {
|
|
2007
|
+
return result;
|
|
1823
2008
|
}
|
|
1824
|
-
await page.
|
|
2009
|
+
await page.sleep(3);
|
|
1825
2010
|
}
|
|
1826
2011
|
|
|
1827
2012
|
throw new TimeoutError(
|
|
@@ -1912,7 +2097,7 @@ export async function waitForChatGPTResponse(page, baselineCount, prompt, timeou
|
|
|
1912
2097
|
const baselinePairCounts = normalizeBaselinePairCounts(options);
|
|
1913
2098
|
|
|
1914
2099
|
while (Date.now() - startTime < timeoutSeconds * 1000) {
|
|
1915
|
-
await page.
|
|
2100
|
+
await page.sleep(3);
|
|
1916
2101
|
if (options.conversationUrl) {
|
|
1917
2102
|
const currentUrl = await currentChatGPTUrl(page);
|
|
1918
2103
|
if (currentUrl && !isSameChatGPTConversation(currentUrl, options.conversationUrl)) {
|
|
@@ -1926,7 +2111,7 @@ export async function waitForChatGPTResponse(page, baselineCount, prompt, timeou
|
|
|
1926
2111
|
continue;
|
|
1927
2112
|
}
|
|
1928
2113
|
|
|
1929
|
-
const messages = await getVisibleMessages(page);
|
|
2114
|
+
const messages = await getVisibleMessages(page, { textOnly: true });
|
|
1930
2115
|
const candidate = findLatestNewAssistantResponse(messages, prompt, baselinePairCounts);
|
|
1931
2116
|
if (!candidate || candidate === String(prompt || '').trim()) continue;
|
|
1932
2117
|
|
|
@@ -2056,7 +2241,7 @@ export async function prepareChatGPTImagePaths(imagePaths) {
|
|
|
2056
2241
|
async function waitForChatGPTUploadPreview(page, fileNames) {
|
|
2057
2242
|
const namesJson = JSON.stringify(fileNames);
|
|
2058
2243
|
for (let attempt = 0; attempt < 10; attempt += 1) {
|
|
2059
|
-
await page.
|
|
2244
|
+
await page.sleep(1);
|
|
2060
2245
|
const ready = requireBooleanEvaluateResult(unwrapEvaluateResult(await page.evaluate(`
|
|
2061
2246
|
(() => {
|
|
2062
2247
|
const names = ${namesJson};
|
|
@@ -2170,15 +2355,36 @@ export async function uploadChatGPTImages(page, imagePaths) {
|
|
|
2170
2355
|
export async function isGenerating(page) {
|
|
2171
2356
|
return requireBooleanEvaluateResult(unwrapEvaluateResult(await page.evaluate(`
|
|
2172
2357
|
(() => {
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2358
|
+
if (document.querySelector('[data-testid="stop-button"]')) return true;
|
|
2359
|
+
|
|
2360
|
+
const controls = Array.from(document.querySelectorAll('button, [role="button"], [aria-label]'));
|
|
2361
|
+
for (const control of controls) {
|
|
2362
|
+
const label = control.getAttribute('aria-label') || '';
|
|
2363
|
+
if (label.includes('Stop generating')) return true;
|
|
2364
|
+
}
|
|
2365
|
+
|
|
2366
|
+
const scopes = [];
|
|
2367
|
+
const turns = document.querySelectorAll('article[data-testid*="conversation-turn"]');
|
|
2368
|
+
const messages = turns.length ? turns : document.querySelectorAll('[data-message-author-role]');
|
|
2369
|
+
if (messages.length) {
|
|
2370
|
+
scopes.push([messages[messages.length - 1], /Thinking|Stop generating/]);
|
|
2371
|
+
}
|
|
2372
|
+
const composer = document.querySelector('#prompt-textarea, [aria-label="Chat with ChatGPT"]');
|
|
2373
|
+
if (composer) {
|
|
2374
|
+
let root = composer;
|
|
2375
|
+
for (let i = 0; i < 4 && root.parentElement; i += 1) root = root.parentElement;
|
|
2376
|
+
scopes.push([root, /Stop generating/]);
|
|
2377
|
+
}
|
|
2378
|
+
|
|
2379
|
+
for (const [scope, pattern] of scopes) {
|
|
2380
|
+
for (const el of [scope, ...scope.querySelectorAll('*')]) {
|
|
2381
|
+
if (el.children.length) continue;
|
|
2382
|
+
if (el.closest('.markdown, pre, code')) continue;
|
|
2383
|
+
const text = (el.textContent || '').trim();
|
|
2384
|
+
if (text && text.length <= 40 && pattern.test(text)) return true;
|
|
2385
|
+
}
|
|
2386
|
+
}
|
|
2387
|
+
return false;
|
|
2182
2388
|
})()
|
|
2183
2389
|
`)), 'chatgpt generation state');
|
|
2184
2390
|
}
|
|
@@ -2319,7 +2525,7 @@ export async function waitForChatGPTImages(page, beforeUrls, timeoutSeconds, con
|
|
|
2319
2525
|
let stableCount = 0;
|
|
2320
2526
|
|
|
2321
2527
|
for (let i = 0; i < maxPolls; i++) {
|
|
2322
|
-
await page.
|
|
2528
|
+
await page.sleep(i === 0 ? 3 : pollIntervalSeconds);
|
|
2323
2529
|
|
|
2324
2530
|
let currentUrl = '';
|
|
2325
2531
|
if (convUrl && convUrl.includes('/c/')) {
|