codex-chatgpt-control 0.5.1-alpha.2 → 0.5.1-alpha.4
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/CHANGELOG.md +42 -0
- package/README.md +43 -0
- package/contracts/v1/fixtures/backend-capabilities.json +40 -1
- package/contracts/v1/fixtures/backend-compatibility.json +21 -0
- package/contracts/v1/fixtures/backend-version.json +6 -1
- package/contracts/v1/fixtures/download-blocked-by-browser.json +22 -0
- package/contracts/v1/fixtures/download-receipt-failed.json +22 -0
- package/contracts/v1/fixtures/download-receipt-timeout.json +22 -0
- package/contracts/v1/fixtures/journal-rpc-indeterminate.json +32 -0
- package/contracts/v1/fixtures/journal-rpc-unsupported-platform.json +32 -0
- package/contracts/v1/fixtures/journal-runtime-unavailable.json +32 -0
- package/contracts/v1/fixtures/operation-action-prepared-event.json +42 -0
- package/contracts/v1/fixtures/operation-action.json +13 -0
- package/contracts/v1/fixtures/operation-artifact-receipt.json +14 -0
- package/contracts/v1/fixtures/operation-artifact-transfer-intent-event.json +24 -0
- package/contracts/v1/fixtures/operation-artifact-transfer-receipt-event.json +26 -0
- package/contracts/v1/fixtures/operation-artifact-transfer-state.json +178 -0
- package/contracts/v1/fixtures/operation-blocker.json +10 -0
- package/contracts/v1/fixtures/operation-collect-request.json +17 -0
- package/contracts/v1/fixtures/operation-collect-result.json +42 -0
- package/contracts/v1/fixtures/operation-control-receipt.json +13 -0
- package/contracts/v1/fixtures/operation-control-request.json +18 -0
- package/contracts/v1/fixtures/operation-control-result.json +31 -0
- package/contracts/v1/fixtures/operation-event.json +18 -0
- package/contracts/v1/fixtures/operation-handle.json +10 -0
- package/contracts/v1/fixtures/operation-inspect-request.json +13 -0
- package/contracts/v1/fixtures/operation-inspect-result.json +205 -0
- package/contracts/v1/fixtures/operation-ownership-baseline-event.json +34 -0
- package/contracts/v1/fixtures/operation-receipt.json +32 -0
- package/contracts/v1/fixtures/operation-recovery-decision.json +7 -0
- package/contracts/v1/fixtures/operation-recovery-observation.json +12 -0
- package/contracts/v1/fixtures/operation-request.json +33 -0
- package/contracts/v1/fixtures/operation-state.json +144 -0
- package/contracts/v1/fixtures/operation-submission-witness-event.json +20 -0
- package/contracts/v1/fixtures/operation-submission-witness.json +11 -0
- package/contracts/v1/fixtures/operation-submit-result.json +16 -0
- package/contracts/v1/fixtures/operation-target-established-event.json +21 -0
- package/contracts/v1/manifest.json +185 -1
- package/contracts/v1/parity-suite.json +106 -8
- package/contracts/v1/schemas/backend-compatibility.schema.json +65 -0
- package/contracts/v1/schemas/backend-request.schema.json +8 -2
- package/contracts/v1/schemas/capabilities.schema.json +81 -1
- package/contracts/v1/schemas/manifest.schema.json +57 -0
- package/contracts/v1/schemas/operation-action.schema.json +155 -0
- package/contracts/v1/schemas/operation-artifact-receipt.schema.json +89 -0
- package/contracts/v1/schemas/operation-blocker.schema.json +70 -0
- package/contracts/v1/schemas/operation-collect-request.schema.json +46 -0
- package/contracts/v1/schemas/operation-collect-result.schema.json +74 -0
- package/contracts/v1/schemas/operation-control-receipt.schema.json +108 -0
- package/contracts/v1/schemas/operation-control-request.schema.json +111 -0
- package/contracts/v1/schemas/operation-control-result.schema.json +112 -0
- package/contracts/v1/schemas/operation-event.schema.json +756 -0
- package/contracts/v1/schemas/operation-handle.schema.json +55 -0
- package/contracts/v1/schemas/operation-inspect-request.schema.json +42 -0
- package/contracts/v1/schemas/operation-inspect-result.schema.json +1662 -0
- package/contracts/v1/schemas/operation-receipt.schema.json +153 -0
- package/contracts/v1/schemas/operation-recovery.schema.json +314 -0
- package/contracts/v1/schemas/operation-request.schema.json +158 -0
- package/contracts/v1/schemas/operation-state.schema.json +691 -0
- package/contracts/v1/schemas/operation-submission-witness.schema.json +48 -0
- package/contracts/v1/schemas/operation-submit-result.schema.json +94 -0
- package/contracts/v1/surface-drift-policy.json +50 -0
- package/contracts/v1/vectors/operation-request-digest-v1.json +43 -0
- package/dist/codex-chatgpt-control-backend.mjs +45882 -9361
- package/dist/codex-chatgpt-control-journal.mjs +5547 -0
- package/dist/codex-chatgpt-control-live-smoke.bundle.mjs +51677 -0
- package/dist/codex-chatgpt-control-release-canary.bundle.mjs +52104 -0
- package/dist/codex-chatgpt-control.bundle.mjs +48392 -10260
- package/dist/src/backend/client.d.ts +103 -2
- package/dist/src/backend/client.js +1436 -97
- package/dist/src/backend/compatibility.d.ts +12 -0
- package/dist/src/backend/compatibility.js +208 -0
- package/dist/src/backend/protocol.d.ts +84 -1
- package/dist/src/backend/protocol.js +31 -5
- package/dist/src/backend/runtime-identity.d.ts +10 -0
- package/dist/src/backend/runtime-identity.js +141 -0
- package/dist/src/backend/session.d.ts +10 -2
- package/dist/src/backend/session.js +478 -7
- package/dist/src/backend/stdio-server.d.ts +4 -1
- package/dist/src/backend/stdio-server.js +240 -28
- package/dist/src/browser/active-composer-file-input.d.ts +9 -0
- package/dist/src/browser/active-composer-file-input.js +33 -0
- package/dist/src/browser/attach.d.ts +4 -1
- package/dist/src/browser/attach.js +136 -28
- package/dist/src/browser/chatgpt-url.d.ts +2 -0
- package/dist/src/browser/chatgpt-url.js +9 -0
- package/dist/src/browser/downloads.d.ts +17 -1
- package/dist/src/browser/downloads.js +150 -28
- package/dist/src/browser/page-state.js +6 -0
- package/dist/src/client.d.ts +43 -0
- package/dist/src/client.js +1279 -59
- package/dist/src/commands/artifacts.js +6 -4
- package/dist/src/commands/chat-popover.d.ts +37 -0
- package/dist/src/commands/chat-popover.js +537 -0
- package/dist/src/commands/configuration.d.ts +5 -0
- package/dist/src/commands/configuration.js +134 -21
- package/dist/src/commands/context.js +10 -3
- package/dist/src/commands/doctor.d.ts +1 -1
- package/dist/src/commands/doctor.js +27 -4
- package/dist/src/commands/experience.d.ts +5 -0
- package/dist/src/commands/experience.js +104 -21
- package/dist/src/commands/files.js +14 -33
- package/dist/src/commands/modes.js +85 -21
- package/dist/src/commands/power-discovery.d.ts +130 -0
- package/dist/src/commands/power-discovery.js +669 -0
- package/dist/src/commands/project-sources.js +325 -31
- package/dist/src/commands/sequence.js +59 -32
- package/dist/src/commands/session.js +19 -6
- package/dist/src/commands/work.js +31 -0
- package/dist/src/dom/composer-text.d.ts +6 -0
- package/dist/src/dom/composer-text.js +85 -0
- package/dist/src/errors.d.ts +9 -0
- package/dist/src/errors.js +22 -0
- package/dist/src/index.d.ts +6 -0
- package/dist/src/index.js +9 -0
- package/dist/src/operations/artifact-output.d.ts +69 -0
- package/dist/src/operations/artifact-output.js +1748 -0
- package/dist/src/operations/artifact-stream.d.ts +19 -0
- package/dist/src/operations/artifact-stream.js +35 -0
- package/dist/src/operations/artifact-transfer.d.ts +149 -0
- package/dist/src/operations/artifact-transfer.js +1312 -0
- package/dist/src/operations/browser-adapter.d.ts +167 -0
- package/dist/src/operations/browser-adapter.js +2103 -0
- package/dist/src/operations/browser-observation.d.ts +110 -0
- package/dist/src/operations/browser-observation.js +1256 -0
- package/dist/src/operations/browser-target.d.ts +105 -0
- package/dist/src/operations/browser-target.js +531 -0
- package/dist/src/operations/canonical.d.ts +4 -0
- package/dist/src/operations/canonical.js +412 -0
- package/dist/src/operations/chatgpt-runtime.d.ts +72 -0
- package/dist/src/operations/chatgpt-runtime.js +1232 -0
- package/dist/src/operations/client.d.ts +138 -0
- package/dist/src/operations/client.js +1145 -0
- package/dist/src/operations/collector.d.ts +195 -0
- package/dist/src/operations/collector.js +1039 -0
- package/dist/src/operations/configuration-routing.d.ts +4 -0
- package/dist/src/operations/configuration-routing.js +14 -0
- package/dist/src/operations/control.d.ts +372 -0
- package/dist/src/operations/control.js +1498 -0
- package/dist/src/operations/file-identity.d.ts +33 -0
- package/dist/src/operations/file-identity.js +153 -0
- package/dist/src/operations/handle.d.ts +19 -0
- package/dist/src/operations/handle.js +727 -0
- package/dist/src/operations/index.d.ts +25 -0
- package/dist/src/operations/index.js +25 -0
- package/dist/src/operations/journal-authority.d.ts +12 -0
- package/dist/src/operations/journal-authority.js +1 -0
- package/dist/src/operations/journal-rpc-client.d.ts +12 -0
- package/dist/src/operations/journal-rpc-client.js +225 -0
- package/dist/src/operations/journal-rpc-protocol.d.ts +32 -0
- package/dist/src/operations/journal-rpc-protocol.js +214 -0
- package/dist/src/operations/journal-rpc-server.d.ts +15 -0
- package/dist/src/operations/journal-rpc-server.js +272 -0
- package/dist/src/operations/journal.d.ts +143 -0
- package/dist/src/operations/journal.js +1957 -0
- package/dist/src/operations/production-attachments.d.ts +118 -0
- package/dist/src/operations/production-attachments.js +1035 -0
- package/dist/src/operations/production-chatgpt-artifacts.d.ts +74 -0
- package/dist/src/operations/production-chatgpt-artifacts.js +1146 -0
- package/dist/src/operations/production-chatgpt-attachments.d.ts +80 -0
- package/dist/src/operations/production-chatgpt-attachments.js +1639 -0
- package/dist/src/operations/production-configuration.d.ts +42 -0
- package/dist/src/operations/production-configuration.js +1544 -0
- package/dist/src/operations/production-primitives.d.ts +53 -0
- package/dist/src/operations/production-primitives.js +856 -0
- package/dist/src/operations/production-work-steer.d.ts +203 -0
- package/dist/src/operations/production-work-steer.js +1218 -0
- package/dist/src/operations/recovery.d.ts +80 -0
- package/dist/src/operations/recovery.js +174 -0
- package/dist/src/operations/runtime-adapter.d.ts +126 -0
- package/dist/src/operations/runtime-adapter.js +802 -0
- package/dist/src/operations/send-once.d.ts +224 -0
- package/dist/src/operations/send-once.js +1081 -0
- package/dist/src/operations/service.d.ts +286 -0
- package/dist/src/operations/service.js +2831 -0
- package/dist/src/operations/staging.d.ts +136 -0
- package/dist/src/operations/staging.js +630 -0
- package/dist/src/operations/state-machine.d.ts +29 -0
- package/dist/src/operations/state-machine.js +2047 -0
- package/dist/src/operations/submission.d.ts +423 -0
- package/dist/src/operations/submission.js +1676 -0
- package/dist/src/operations/transactional-chat-power.d.ts +17 -0
- package/dist/src/operations/transactional-chat-power.js +212 -0
- package/dist/src/operations/turn-ownership.d.ts +202 -0
- package/dist/src/operations/turn-ownership.js +700 -0
- package/dist/src/operations/types.d.ts +454 -0
- package/dist/src/operations/types.js +20 -0
- package/dist/src/operations/wire-requests.d.ts +21 -0
- package/dist/src/operations/wire-requests.js +396 -0
- package/dist/src/operations/wire-results.d.ts +97 -0
- package/dist/src/operations/wire-results.js +818 -0
- package/dist/src/runner/responses.d.ts +3 -1
- package/dist/src/runner/responses.js +19 -1
- package/dist/src/runner/result.js +227 -55
- package/dist/src/runner/types.d.ts +12 -0
- package/dist/src/runtime/command-routing.d.ts +149 -0
- package/dist/src/runtime/command-routing.js +431 -0
- package/dist/src/runtime/coordinated-browser.d.ts +24 -0
- package/dist/src/runtime/coordinated-browser.js +315 -0
- package/dist/src/runtime/coordinated-page.d.ts +41 -0
- package/dist/src/runtime/coordinated-page.js +651 -0
- package/dist/src/runtime/operation-context.d.ts +142 -0
- package/dist/src/runtime/operation-context.js +410 -0
- package/dist/src/runtime/runtime-session.d.ts +95 -0
- package/dist/src/runtime/runtime-session.js +314 -0
- package/dist/src/runtime/tab-coordinator.d.ts +200 -0
- package/dist/src/runtime/tab-coordinator.js +1200 -0
- package/dist/src/runtime/value-boundaries.d.ts +18 -0
- package/dist/src/runtime/value-boundaries.js +49 -0
- package/dist/src/safety/blockers.js +8 -1
- package/dist/src/safety/untrusted-output.js +2 -1
- package/dist/src/scripts/backend-server.js +4 -1
- package/dist/src/scripts/capture-surface-profile.js +7 -2
- package/dist/src/scripts/journal-server.d.ts +2 -0
- package/dist/src/scripts/journal-server.js +37 -0
- package/dist/src/scripts/live-smoke/harness.js +79 -7
- package/dist/src/scripts/live-smoke/scenarios.d.ts +42 -1
- package/dist/src/scripts/live-smoke/scenarios.js +147 -30
- package/dist/src/scripts/live-smoke/transactional.d.ts +17 -0
- package/dist/src/scripts/live-smoke/transactional.js +254 -0
- package/dist/src/scripts/live-smoke/types.d.ts +3 -0
- package/dist/src/scripts/release-canary-module.js +17 -4
- package/dist/src/types.d.ts +38 -1
- package/package.json +8 -3
- package/references/2026-08-16-transactional-operations.md +459 -0
- package/references/2026-09-06-journal-service.md +140 -0
- package/references/agents-runner.md +34 -0
- package/references/backend-protocol.md +176 -0
- package/references/python-parity.md +137 -0
- package/references/responses-adapter.md +19 -0
- package/references/streaming.md +6 -0
|
@@ -1,39 +1,161 @@
|
|
|
1
1
|
import { copyFile, mkdir, stat } from "node:fs/promises";
|
|
2
2
|
import { basename, join, resolve } from "node:path";
|
|
3
|
-
import {
|
|
3
|
+
import { ChatGPTControlError } from "../errors.js";
|
|
4
|
+
import { createDeadline, remainingMs } from "../commands/deadline.js";
|
|
5
|
+
import { withTimeout } from "../commands/timeouts.js";
|
|
6
|
+
import { coordinatedEventRegistrationBarrier, withCoordinatedMutationGuard } from "../runtime/coordinated-page.js";
|
|
7
|
+
export class DownloadReceiptTimeoutError extends ChatGPTControlError {
|
|
8
|
+
constructor(stage) {
|
|
9
|
+
super(`Download ${stage} did not complete before the deadline. Completion is unverified; inspect the existing download before retrying.`, "download_unavailable", false, undefined, { code: "download_receipt_timeout", resumable: false });
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
export class DownloadBrowserBlockedError extends ChatGPTControlError {
|
|
13
|
+
constructor() {
|
|
14
|
+
super("Chrome displayed ERR_BLOCKED_BY_CLIENT during the download. Inspect the existing download and Chrome restrictions before retrying; completion is unverified.", "download_unavailable", false, undefined, { code: "download_blocked_by_browser", resumable: false });
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
export class DownloadReceiptFailedError extends ChatGPTControlError {
|
|
18
|
+
constructor() {
|
|
19
|
+
super("The browser did not provide a verified download receipt. Inspect the existing download before retrying; completion is unverified.", "download_unavailable", false, undefined, { code: "download_receipt_failed", resumable: false });
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
export function isTerminalDownloadError(error) {
|
|
23
|
+
return error instanceof DownloadReceiptTimeoutError || error instanceof DownloadBrowserBlockedError || error instanceof DownloadReceiptFailedError;
|
|
24
|
+
}
|
|
25
|
+
export function isTerminalDownloadCode(code) {
|
|
26
|
+
return code === "download_receipt_timeout" || code === "download_blocked_by_browser" || code === "download_receipt_failed";
|
|
27
|
+
}
|
|
28
|
+
async function checkBrowserDownloadError(page, deadline) {
|
|
29
|
+
if (typeof page.evaluate !== "function")
|
|
30
|
+
return;
|
|
31
|
+
// A missing or stalled diagnostic must leave time for the native receipt.
|
|
32
|
+
// Both probes are read-only, bounded by the existing operation deadline,
|
|
33
|
+
// and return an enum instead of exporting error-page URLs or body text.
|
|
34
|
+
const timeoutMs = Math.min(1000, Math.floor(remainingMs(deadline) / 4));
|
|
35
|
+
if (timeoutMs <= 0)
|
|
36
|
+
return;
|
|
37
|
+
let state;
|
|
38
|
+
try {
|
|
39
|
+
state = await withTimeout(page.evaluate(function inspectBrowserDownloadError() {
|
|
40
|
+
if (!document.body?.getAttribute("class")?.split(/\s+/).includes("neterror"))
|
|
41
|
+
return "unavailable";
|
|
42
|
+
const frames = document.querySelectorAll("#main-frame-error");
|
|
43
|
+
if (frames.length !== 1)
|
|
44
|
+
return "unavailable";
|
|
45
|
+
const codes = frames[0].querySelectorAll(".error-code");
|
|
46
|
+
return codes.length === 1 && codes[0].textContent?.trim() === "ERR_BLOCKED_BY_CLIENT"
|
|
47
|
+
? "blocked_by_client" : "unavailable";
|
|
48
|
+
}, undefined, { timeoutMs }), timeoutMs, "Browser download diagnostic timed out.");
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
if (state === "blocked_by_client")
|
|
54
|
+
throw new DownloadBrowserBlockedError();
|
|
55
|
+
}
|
|
56
|
+
async function downloadStep(deadline, stage, run, capMs) {
|
|
57
|
+
const timeoutMs = Math.min(remainingMs(deadline), capMs ?? Number.MAX_SAFE_INTEGER);
|
|
58
|
+
const timeoutError = new DownloadReceiptTimeoutError(stage);
|
|
59
|
+
if (timeoutMs <= 0)
|
|
60
|
+
throw timeoutError;
|
|
61
|
+
try {
|
|
62
|
+
return await withTimeout(run(), timeoutMs, timeoutError.message);
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
if (error instanceof Error && error.message === timeoutError.message)
|
|
66
|
+
throw timeoutError;
|
|
67
|
+
throw error;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
4
70
|
export async function waitForDownloadFromClick(page, click, destDir, timeoutMs, filenameHint) {
|
|
71
|
+
if (!Number.isFinite(timeoutMs) || timeoutMs <= 0 || timeoutMs > 2_147_483_647) {
|
|
72
|
+
throw new Error("Download timeout must be positive and within the supported timer range.");
|
|
73
|
+
}
|
|
74
|
+
const deadline = createDeadline(timeoutMs);
|
|
75
|
+
await checkBrowserDownloadError(page, deadline);
|
|
5
76
|
const absoluteDest = resolve(destDir);
|
|
6
|
-
await mkdir(absoluteDest, { recursive: true });
|
|
7
|
-
|
|
8
|
-
if (downloadPromise === undefined) {
|
|
77
|
+
await downloadStep(deadline, "destination preparation", () => mkdir(absoluteDest, { recursive: true }));
|
|
78
|
+
if (typeof page.waitForEvent !== "function") {
|
|
9
79
|
throw new Error("The active browser page does not expose download events.");
|
|
10
80
|
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
81
|
+
// Arm before activation. Promise.all observes both rejections immediately,
|
|
82
|
+
// including a late event rejection after a failed or timed-out click.
|
|
83
|
+
const nativeTimeoutMs = remainingMs(deadline);
|
|
84
|
+
if (nativeTimeoutMs <= 0)
|
|
85
|
+
throw new DownloadReceiptTimeoutError("event registration");
|
|
86
|
+
const activation = new AbortController();
|
|
87
|
+
let failure;
|
|
88
|
+
const assertActive = () => {
|
|
89
|
+
if (failure !== undefined)
|
|
90
|
+
throw failure;
|
|
91
|
+
if (activation.signal.aborted || remainingMs(deadline) <= 0)
|
|
92
|
+
throw new DownloadReceiptTimeoutError("control click");
|
|
93
|
+
};
|
|
94
|
+
try {
|
|
95
|
+
const rawWait = page.waitForEvent("download", { timeout: nativeTimeoutMs, timeoutMs: nativeTimeoutMs });
|
|
96
|
+
const registration = coordinatedEventRegistrationBarrier(rawWait);
|
|
97
|
+
let receiptFailed = false;
|
|
98
|
+
const downloadPromise = downloadStep(deadline, "event receipt", () => rawWait).catch(error => {
|
|
99
|
+
receiptFailed = true;
|
|
100
|
+
failure = isTerminalDownloadError(error) ? error : new DownloadReceiptFailedError();
|
|
101
|
+
activation.abort(failure);
|
|
102
|
+
throw failure;
|
|
103
|
+
});
|
|
104
|
+
const [download] = await Promise.all([
|
|
105
|
+
downloadPromise,
|
|
106
|
+
(async () => {
|
|
107
|
+
// Actor fairness may choose a queued mutation before another read.
|
|
108
|
+
// Registration must finish before the activating click is even queued.
|
|
109
|
+
if (registration !== undefined)
|
|
110
|
+
await downloadStep(deadline, "event registration", () => registration);
|
|
111
|
+
try {
|
|
112
|
+
await downloadStep(deadline, "control click", () => withCoordinatedMutationGuard(activation.signal, assertActive, click), 10_000);
|
|
113
|
+
}
|
|
114
|
+
catch (error) {
|
|
115
|
+
if (!receiptFailed)
|
|
116
|
+
await checkBrowserDownloadError(page, deadline);
|
|
117
|
+
throw error;
|
|
118
|
+
}
|
|
119
|
+
if (!receiptFailed)
|
|
120
|
+
await checkBrowserDownloadError(page, deadline);
|
|
121
|
+
})()
|
|
122
|
+
]);
|
|
123
|
+
// saveAs is already a complete capability; an optional path() call can hang
|
|
124
|
+
// on bridge implementations and is unnecessary when saveAs is available.
|
|
125
|
+
const sourcePath = typeof download.saveAs !== "function" && typeof download.path === "function"
|
|
126
|
+
? await downloadStep(deadline, "source path", () => download.path({ timeoutMs: remainingMs(deadline) })) : null;
|
|
127
|
+
const suggestedFilename = filenameHint
|
|
128
|
+
?? download.suggestedFilename?.()
|
|
129
|
+
?? (sourcePath === null ? undefined : basename(sourcePath))
|
|
130
|
+
?? `chatgpt-download-${Date.now()}`;
|
|
131
|
+
const targetPath = join(absoluteDest, basename(suggestedFilename));
|
|
132
|
+
if (typeof download.saveAs === "function") {
|
|
133
|
+
await downloadStep(deadline, "file save", () => download.saveAs(targetPath));
|
|
134
|
+
}
|
|
135
|
+
else if (sourcePath !== null) {
|
|
136
|
+
if (resolve(sourcePath) !== resolve(targetPath)) {
|
|
137
|
+
await downloadStep(deadline, "file copy", () => copyFile(sourcePath, targetPath));
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
throw new Error("The browser download object exposes neither saveAs() nor a completed local path().");
|
|
25
142
|
}
|
|
143
|
+
const saved = await downloadStep(deadline, "file verification", () => stat(targetPath));
|
|
144
|
+
if (saved.size <= 0) {
|
|
145
|
+
throw new Error(`Downloaded file is empty: ${targetPath}`);
|
|
146
|
+
}
|
|
147
|
+
return {
|
|
148
|
+
path: targetPath,
|
|
149
|
+
suggestedFilename,
|
|
150
|
+
bytes: saved.size
|
|
151
|
+
};
|
|
26
152
|
}
|
|
27
|
-
|
|
28
|
-
throw
|
|
153
|
+
catch (error) {
|
|
154
|
+
throw failure ?? (isTerminalDownloadError(error) ? error : new DownloadReceiptFailedError());
|
|
29
155
|
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
156
|
+
finally {
|
|
157
|
+
// Cancels locally queued activation only. A native download already in
|
|
158
|
+
// progress, or its native event listener, is not claimed to be cancelled.
|
|
159
|
+
activation.abort();
|
|
33
160
|
}
|
|
34
|
-
return {
|
|
35
|
-
path: targetPath,
|
|
36
|
-
suggestedFilename,
|
|
37
|
-
bytes: saved.size
|
|
38
|
-
};
|
|
39
161
|
}
|
|
@@ -2,6 +2,7 @@ import { classifyVisibleText } from "../safety/blockers.js";
|
|
|
2
2
|
import { compactVisibleText } from "../safety/redaction.js";
|
|
3
3
|
import { escapeRegExp, localeLabels } from "../dom/locale-labels.js";
|
|
4
4
|
import { withTimeout } from "../commands/timeouts.js";
|
|
5
|
+
import { chatGPTAttachmentContextUrl } from "./chatgpt-url.js";
|
|
5
6
|
export function parseConversationId(url) {
|
|
6
7
|
let parsed;
|
|
7
8
|
try {
|
|
@@ -19,6 +20,11 @@ export function parseConversationId(url) {
|
|
|
19
20
|
export async function readPageState(page) {
|
|
20
21
|
const rawUrl = typeof page.url === "function" ? await Promise.resolve(page.url()).catch(() => "") : "";
|
|
21
22
|
const url = typeof rawUrl === "string" ? rawUrl : "";
|
|
23
|
+
// This is a file transfer endpoint, not a conversation surface. Keep the
|
|
24
|
+
// internal URL for origin checks without inspecting error-page content.
|
|
25
|
+
if (chatGPTAttachmentContextUrl(url) !== undefined) {
|
|
26
|
+
return { url, visibleText: "", signedIn: false };
|
|
27
|
+
}
|
|
22
28
|
const rawTitle = typeof page.title === "function" ? await page.title().catch(() => undefined) : undefined;
|
|
23
29
|
const title = typeof rawTitle === "string" ? rawTitle : undefined;
|
|
24
30
|
const surface = await readPageSurfaceSnapshot(page);
|
package/dist/src/client.d.ts
CHANGED
|
@@ -6,6 +6,12 @@ import type { ChatGPTAgent, ChatGPTAgentConfig, ChatGPTResponse, ChatGPTRunner,
|
|
|
6
6
|
import { type ChatGPTResponsesCreateArgs } from "./runner/responses.js";
|
|
7
7
|
import { type ReportRedactionOptions } from "./safety/report-redaction.js";
|
|
8
8
|
import { type BlockerExplanation, type ExplainBlockerOptions } from "./diagnostics/blockers.js";
|
|
9
|
+
import { type OperationAdapterFactory, type OperationControlAdapterFactory, type OperationClientCollectOptions, type OperationClientControlOptions, type OperationClientRunOptions, type OperationClientSubmitOptions, type OperationHandleAdapterFactory } from "./operations/client.js";
|
|
10
|
+
import { type OperationBrowserAdapter } from "./operations/service.js";
|
|
11
|
+
import type { OperationControlRequestV1, OperationHandleV1, OperationSubmitRequestV1 } from "./operations/types.js";
|
|
12
|
+
import type { CollectorResult } from "./operations/collector.js";
|
|
13
|
+
import type { ControlResult } from "./operations/control.js";
|
|
14
|
+
import type { OperationInspectResult, OperationRunResult, OperationSubmitResult } from "./operations/service.js";
|
|
9
15
|
export type ChatGPTClientOptions = RuntimeEnv & {
|
|
10
16
|
defaults?: {
|
|
11
17
|
experience?: Exclude<ChatGPTExperience, "unknown">;
|
|
@@ -18,7 +24,41 @@ export type ChatGPTClientOptions = RuntimeEnv & {
|
|
|
18
24
|
};
|
|
19
25
|
limits?: Partial<RunLimits>;
|
|
20
26
|
reporting?: RunReportOptions;
|
|
27
|
+
/** Additive transactional operation surface. Construction remains synchronous; journal opening is lazy. */
|
|
28
|
+
operations?: ChatGPTOperationsOptions;
|
|
21
29
|
};
|
|
30
|
+
/**
|
|
31
|
+
* Configuration for the additive transactional operation surface.
|
|
32
|
+
*
|
|
33
|
+
* The default state root is the platform application-state directory owned by
|
|
34
|
+
* `OperationJournal`. Set `stateRoot` explicitly when multiple cooperating
|
|
35
|
+
* clients must share a project-local journal. Browser adapters are opt-in:
|
|
36
|
+
* without one, durable inspection still works but browser-touching calls fail
|
|
37
|
+
* closed with an adapter blocker.
|
|
38
|
+
*/
|
|
39
|
+
export type ChatGPTOperationsOptions = Readonly<{
|
|
40
|
+
stateRoot?: string;
|
|
41
|
+
/** Explicit private-file connection to a normal Node journal authority. */
|
|
42
|
+
journalService?: Readonly<{
|
|
43
|
+
descriptorPath: string;
|
|
44
|
+
timeoutMs?: number;
|
|
45
|
+
}>;
|
|
46
|
+
adapter?: OperationBrowserAdapter;
|
|
47
|
+
adapterFactory?: OperationAdapterFactory;
|
|
48
|
+
handleAdapterFactory?: OperationHandleAdapterFactory;
|
|
49
|
+
/** Fresh request-local adapter for Stop or Work steer; never cached. */
|
|
50
|
+
controlAdapterFactory?: OperationControlAdapterFactory;
|
|
51
|
+
maxCachedAdapters?: number;
|
|
52
|
+
maxCasRetries?: number;
|
|
53
|
+
}>;
|
|
54
|
+
/** Stable, lazily initialized facade exposed as `chatgpt.operations`. */
|
|
55
|
+
export type ChatGPTOperations = Readonly<{
|
|
56
|
+
submit(request: OperationSubmitRequestV1, options?: OperationClientSubmitOptions): Promise<OperationSubmitResult>;
|
|
57
|
+
collect(handle: OperationHandleV1, options?: OperationClientCollectOptions): Promise<CollectorResult>;
|
|
58
|
+
inspect(handle: OperationHandleV1): Promise<OperationInspectResult>;
|
|
59
|
+
control(request: OperationControlRequestV1, options?: OperationClientControlOptions): Promise<ControlResult>;
|
|
60
|
+
run(request: OperationSubmitRequestV1, options?: OperationClientRunOptions): Promise<OperationRunResult>;
|
|
61
|
+
}>;
|
|
22
62
|
export type RunLimits = {
|
|
23
63
|
maxPromptsPerRun: number;
|
|
24
64
|
maxThreadsOpenedPerRun: number;
|
|
@@ -58,6 +98,8 @@ export type FileInput = string | {
|
|
|
58
98
|
};
|
|
59
99
|
export type AskWorkflowArgs = {
|
|
60
100
|
prompt: string;
|
|
101
|
+
/** Caller-owned durable identity. Supplying it opts this invocation into the transactional operation path. */
|
|
102
|
+
operationId?: string;
|
|
61
103
|
thread?: WorkflowThread;
|
|
62
104
|
existingTab?: BootstrapArgs["existingTab"];
|
|
63
105
|
preferExistingTab?: boolean;
|
|
@@ -107,6 +149,7 @@ export type ChatGPTClient = {
|
|
|
107
149
|
agent<TOutput = string>(config: ChatGPTAgentConfig<TOutput>): ChatGPTAgent<TOutput>;
|
|
108
150
|
run<TOutput = string>(agent: ChatGPTAgent<TOutput>, input: ChatGPTRunInput): Promise<ChatGPTRunResult<TOutput>>;
|
|
109
151
|
runner: ChatGPTRunner;
|
|
152
|
+
operations: ChatGPTOperations;
|
|
110
153
|
responses: {
|
|
111
154
|
create(args: ChatGPTResponsesCreateArgs | Record<string, unknown>): Promise<ChatGPTResponse>;
|
|
112
155
|
};
|