agents-relay 2.0.95 → 2.0.96
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/adapters.js +2 -53
- package/package.json +1 -1
package/dist/adapters.js
CHANGED
|
@@ -228,63 +228,12 @@ export async function ensureChatGptBrowserWorkspace(command = process.env.AGENTS
|
|
|
228
228
|
}
|
|
229
229
|
await admin.ensureWorkspace(CHATGPT_BROWSER_WORKSPACE, CHATGPT_BROWSER_WORKSPACE_POOL_SIZE);
|
|
230
230
|
}
|
|
231
|
-
|
|
232
|
-
* The upstream new-turn action accepts idempotency_key but does not enforce it.
|
|
233
|
-
* Inspect the current thread before resubmitting after an ambiguous exit.
|
|
234
|
-
* If the transcript is not observable, fail closed rather than duplicate.
|
|
235
|
-
*/
|
|
236
|
-
async function findExistingReviewTurn(cli, sessionId, delivery, signal) {
|
|
237
|
-
const pathname = delivery.projectId
|
|
238
|
-
? `/g/${encodeURIComponent(delivery.projectId)}/c/${encodeURIComponent(delivery.threadId)}`
|
|
239
|
-
: `/c/${encodeURIComponent(delivery.threadId)}`;
|
|
240
|
-
const marker = `Relay delivery ID: ${delivery.requestId}`;
|
|
241
|
-
const inspectJs = `(() => {
|
|
242
|
-
const legacy = [...document.querySelectorAll('[data-message-author-role="user"]')]
|
|
243
|
-
.map(e => ({text: (e.innerText || '').trim(), id: e.getAttribute('data-message-id') || ''})).filter(x => x.text);
|
|
244
|
-
if (legacy.length) return legacy;
|
|
245
|
-
return [...document.querySelectorAll('h4')].filter(e => (e.innerText || '').trim() === 'You said:')
|
|
246
|
-
.map((e,i) => ({text: (e.parentElement?.innerText || '').trim(), id: 'dom-user-' + i})).filter(x => x.text);
|
|
247
|
-
})()`;
|
|
248
|
-
const script = [
|
|
249
|
-
'import json, time',
|
|
250
|
-
'from urllib.parse import urlsplit',
|
|
251
|
-
`url = ${JSON.stringify(`https://chatgpt.com${pathname}`)}`,
|
|
252
|
-
`marker = ${JSON.stringify(marker)}`,
|
|
253
|
-
'goto_url(url)',
|
|
254
|
-
'wait_for_load()',
|
|
255
|
-
'if urlsplit(page_info().get("url", "")).path.rstrip("/") != urlsplit(url).path.rstrip("/"): raise RuntimeError("review thread redirect mismatch")',
|
|
256
|
-
'turns = []',
|
|
257
|
-
'for attempt in range(30):',
|
|
258
|
-
` turns = js(${JSON.stringify(inspectJs)}) or []`,
|
|
259
|
-
' if turns: break',
|
|
260
|
-
' time.sleep(0.5)',
|
|
261
|
-
'if not turns: raise RuntimeError("review thread transcript unavailable; refusing ambiguous resubmission")',
|
|
262
|
-
'matches = [turn for turn in turns if marker in turn.get("text", "")]',
|
|
263
|
-
'if len(matches) > 1: raise RuntimeError("duplicate review delivery detected; manual reconciliation required")',
|
|
264
|
-
'print(json.dumps({"found": bool(matches), "user_message_id": matches[0].get("id") if matches else None}), flush=True)',
|
|
265
|
-
].join('\n');
|
|
266
|
-
const envelope = parseWorkspaceJson(await browserWorkspaceCommand(cli, ['session', 'exec', sessionId], script, signal));
|
|
267
|
-
if (envelope.ok !== true || typeof envelope.stdout !== 'string')
|
|
268
|
-
throw new Error('review thread inspection returned no executable result');
|
|
269
|
-
const observation = parseWorkspaceJson(envelope.stdout);
|
|
270
|
-
if (typeof observation.found !== 'boolean')
|
|
271
|
-
throw new Error('review thread inspection returned no authoritative result');
|
|
272
|
-
if (!observation.found)
|
|
273
|
-
return null;
|
|
274
|
-
return { status: 'submitted', mode: 'new-turn', thread_id: delivery.threadId, project_id: delivery.projectId,
|
|
275
|
-
verified_by: 'existing-user-turn', user_message_id: typeof observation.user_message_id === 'string' ? observation.user_message_id : null };
|
|
276
|
-
}
|
|
277
|
-
async function runBrowserWorker(cli, configFile, signal, action = 'temporary-submit', delivery) {
|
|
231
|
+
async function runBrowserWorker(cli, configFile, signal, action = 'temporary-submit') {
|
|
278
232
|
const session = parseWorkspaceJson(await browserWorkspaceCommand(cli, ['session', 'start', '--workspace', CHATGPT_BROWSER_WORKSPACE], undefined, signal));
|
|
279
233
|
const sessionId = session.session_id;
|
|
280
234
|
if (typeof sessionId !== 'string' || !sessionId)
|
|
281
235
|
throw new Error('browser-workspace session start returned no session_id');
|
|
282
236
|
try {
|
|
283
|
-
if (delivery) {
|
|
284
|
-
const existing = await findExistingReviewTurn(cli, sessionId, delivery, signal);
|
|
285
|
-
if (existing)
|
|
286
|
-
return JSON.stringify(existing);
|
|
287
|
-
}
|
|
288
237
|
return await browserWorkspaceCommand(cli, ['platform', 'run', 'chatgpt', action, '--session-id', sessionId, '--config', configFile], undefined, signal);
|
|
289
238
|
}
|
|
290
239
|
finally {
|
|
@@ -310,7 +259,7 @@ function browserWorkerRunner() {
|
|
|
310
259
|
if (signal.aborted)
|
|
311
260
|
throw new Error('browser-worker execution aborted');
|
|
312
261
|
const action = delivery ? 'new-turn' : 'temporary-submit';
|
|
313
|
-
const output = await runBrowserWorker(cli, configFile, signal, action
|
|
262
|
+
const output = await runBrowserWorker(cli, configFile, signal, action);
|
|
314
263
|
return JSON.stringify(parseDriverJson(output));
|
|
315
264
|
}
|
|
316
265
|
finally {
|