@elizaos/plugin-browser 2.0.0-alpha.9 → 2.0.11-beta.7
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/LICENSE +21 -0
- package/README.md +98 -83
- package/auto-enable.ts +24 -0
- package/dist/actions/browser-autofill-login.d.ts +43 -0
- package/dist/actions/browser-autofill-login.d.ts.map +1 -0
- package/dist/actions/browser-autofill-login.js +278 -0
- package/dist/actions/browser-autofill-login.js.map +1 -0
- package/dist/actions/browser.d.ts +11 -0
- package/dist/actions/browser.d.ts.map +1 -0
- package/dist/actions/browser.js +412 -0
- package/dist/actions/browser.js.map +1 -0
- package/dist/actions/manage-browser-bridge.d.ts +34 -0
- package/dist/actions/manage-browser-bridge.d.ts.map +1 -0
- package/dist/actions/manage-browser-bridge.js +572 -0
- package/dist/actions/manage-browser-bridge.js.map +1 -0
- package/dist/bridge-policy.d.ts +10 -0
- package/dist/bridge-policy.d.ts.map +1 -0
- package/dist/bridge-policy.js +37 -0
- package/dist/bridge-policy.js.map +1 -0
- package/dist/bridge-readiness.d.ts +16 -0
- package/dist/bridge-readiness.d.ts.map +1 -0
- package/dist/bridge-readiness.js +82 -0
- package/dist/bridge-readiness.js.map +1 -0
- package/dist/bridge-records.d.ts +9 -0
- package/dist/bridge-records.d.ts.map +1 -0
- package/dist/bridge-records.js +37 -0
- package/dist/bridge-records.js.map +1 -0
- package/dist/browser-capture-hooks.d.ts +9 -0
- package/dist/browser-capture-hooks.d.ts.map +1 -0
- package/dist/browser-capture-hooks.js +15 -0
- package/dist/browser-capture-hooks.js.map +1 -0
- package/dist/browser-service.d.ts +103 -0
- package/dist/browser-service.d.ts.map +1 -0
- package/dist/browser-service.js +186 -0
- package/dist/browser-service.js.map +1 -0
- package/dist/browser-workspace-hooks.d.ts +14 -0
- package/dist/browser-workspace-hooks.d.ts.map +1 -0
- package/dist/browser-workspace-hooks.js +15 -0
- package/dist/browser-workspace-hooks.js.map +1 -0
- package/dist/companion-auth.d.ts +34 -0
- package/dist/companion-auth.d.ts.map +1 -0
- package/dist/companion-auth.js +98 -0
- package/dist/companion-auth.js.map +1 -0
- package/dist/contracts.d.ts +284 -0
- package/dist/contracts.d.ts.map +1 -0
- package/dist/contracts.js +56 -0
- package/dist/contracts.js.map +1 -0
- package/dist/index.d.ts +30 -16
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +76 -90
- package/dist/index.js.map +1 -1
- package/dist/lifeops-session-contracts.d.ts +46 -0
- package/dist/lifeops-session-contracts.d.ts.map +1 -0
- package/dist/lifeops-session-contracts.js +1 -0
- package/dist/lifeops-session-contracts.js.map +1 -0
- package/dist/message-adapter.d.ts +9 -0
- package/dist/message-adapter.d.ts.map +1 -0
- package/dist/message-adapter.js +104 -0
- package/dist/message-adapter.js.map +1 -0
- package/dist/packaging.d.ts +27 -0
- package/dist/packaging.d.ts.map +1 -0
- package/dist/packaging.js +571 -0
- package/dist/packaging.js.map +1 -0
- package/dist/password-manager-bridge.d.ts +50 -0
- package/dist/password-manager-bridge.d.ts.map +1 -0
- package/dist/password-manager-bridge.js +437 -0
- package/dist/password-manager-bridge.js.map +1 -0
- package/dist/plugin.d.ts +10 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +168 -0
- package/dist/plugin.js.map +1 -0
- package/dist/providers/workspace.d.ts +13 -0
- package/dist/providers/workspace.d.ts.map +1 -0
- package/dist/providers/workspace.js +64 -0
- package/dist/providers/workspace.js.map +1 -0
- package/dist/routes/bridge.d.ts +37 -0
- package/dist/routes/bridge.d.ts.map +1 -0
- package/dist/routes/bridge.js +844 -0
- package/dist/routes/bridge.js.map +1 -0
- package/dist/routes/workspace-account-gate.d.ts +29 -0
- package/dist/routes/workspace-account-gate.d.ts.map +1 -0
- package/dist/routes/workspace-account-gate.js +147 -0
- package/dist/routes/workspace-account-gate.js.map +1 -0
- package/dist/routes/workspace-setup.d.ts +10 -0
- package/dist/routes/workspace-setup.d.ts.map +1 -0
- package/dist/routes/workspace-setup.js +65 -0
- package/dist/routes/workspace-setup.js.map +1 -0
- package/dist/routes/workspace.d.ts +20 -0
- package/dist/routes/workspace.d.ts.map +1 -0
- package/dist/routes/workspace.js +276 -0
- package/dist/routes/workspace.js.map +1 -0
- package/dist/schema.d.ts +2326 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +133 -0
- package/dist/schema.js.map +1 -0
- package/dist/service.d.ts +30 -0
- package/dist/service.d.ts.map +1 -0
- package/dist/service.js +5 -0
- package/dist/service.js.map +1 -0
- package/dist/targets/bridge-target.d.ts +31 -0
- package/dist/targets/bridge-target.d.ts.map +1 -0
- package/dist/targets/bridge-target.js +98 -0
- package/dist/targets/bridge-target.js.map +1 -0
- package/dist/targets/stagehand-target.d.ts +3 -0
- package/dist/targets/stagehand-target.d.ts.map +1 -0
- package/dist/targets/stagehand-target.js +187 -0
- package/dist/targets/stagehand-target.js.map +1 -0
- package/dist/workspace/browser-capture.d.ts +41 -0
- package/dist/workspace/browser-capture.d.ts.map +1 -0
- package/dist/workspace/browser-capture.js +159 -0
- package/dist/workspace/browser-capture.js.map +1 -0
- package/dist/workspace/browser-workspace-desktop.d.ts +19 -0
- package/dist/workspace/browser-workspace-desktop.d.ts.map +1 -0
- package/dist/workspace/browser-workspace-desktop.js +1578 -0
- package/dist/workspace/browser-workspace-desktop.js.map +1 -0
- package/dist/workspace/browser-workspace-elements.d.ts +42 -0
- package/dist/workspace/browser-workspace-elements.d.ts.map +1 -0
- package/dist/workspace/browser-workspace-elements.js +547 -0
- package/dist/workspace/browser-workspace-elements.js.map +1 -0
- package/dist/workspace/browser-workspace-forms.d.ts +19 -0
- package/dist/workspace/browser-workspace-forms.d.ts.map +1 -0
- package/dist/workspace/browser-workspace-forms.js +277 -0
- package/dist/workspace/browser-workspace-forms.js.map +1 -0
- package/dist/workspace/browser-workspace-helpers.d.ts +32 -0
- package/dist/workspace/browser-workspace-helpers.d.ts.map +1 -0
- package/dist/workspace/browser-workspace-helpers.js +232 -0
- package/dist/workspace/browser-workspace-helpers.js.map +1 -0
- package/dist/workspace/browser-workspace-jsdom.d.ts +16 -0
- package/dist/workspace/browser-workspace-jsdom.d.ts.map +1 -0
- package/dist/workspace/browser-workspace-jsdom.js +233 -0
- package/dist/workspace/browser-workspace-jsdom.js.map +1 -0
- package/dist/workspace/browser-workspace-network.d.ts +7 -0
- package/dist/workspace/browser-workspace-network.d.ts.map +1 -0
- package/dist/workspace/browser-workspace-network.js +145 -0
- package/dist/workspace/browser-workspace-network.js.map +1 -0
- package/dist/workspace/browser-workspace-snapshots.d.ts +14 -0
- package/dist/workspace/browser-workspace-snapshots.d.ts.map +1 -0
- package/dist/workspace/browser-workspace-snapshots.js +144 -0
- package/dist/workspace/browser-workspace-snapshots.js.map +1 -0
- package/dist/workspace/browser-workspace-state.d.ts +24 -0
- package/dist/workspace/browser-workspace-state.d.ts.map +1 -0
- package/dist/workspace/browser-workspace-state.js +155 -0
- package/dist/workspace/browser-workspace-state.js.map +1 -0
- package/dist/workspace/browser-workspace-types.d.ts +345 -0
- package/dist/workspace/browser-workspace-types.d.ts.map +1 -0
- package/dist/workspace/browser-workspace-types.js +11 -0
- package/dist/workspace/browser-workspace-types.js.map +1 -0
- package/dist/workspace/browser-workspace-web.d.ts +8 -0
- package/dist/workspace/browser-workspace-web.d.ts.map +1 -0
- package/dist/workspace/browser-workspace-web.js +1342 -0
- package/dist/workspace/browser-workspace-web.js.map +1 -0
- package/dist/workspace/browser-workspace.d.ts +39 -0
- package/dist/workspace/browser-workspace.d.ts.map +1 -0
- package/dist/workspace/browser-workspace.js +958 -0
- package/dist/workspace/browser-workspace.js.map +1 -0
- package/dist/workspace/index.d.ts +26 -0
- package/dist/workspace/index.d.ts.map +1 -0
- package/dist/workspace/index.js +3 -0
- package/dist/workspace/index.js.map +1 -0
- package/dist/workspace.d.ts +2 -0
- package/dist/workspace.d.ts.map +1 -0
- package/dist/workspace.js +2 -0
- package/dist/workspace.js.map +1 -0
- package/package.json +71 -110
- package/dist/actions/click.d.ts +0 -3
- package/dist/actions/click.d.ts.map +0 -1
- package/dist/actions/click.js +0 -158
- package/dist/actions/click.js.map +0 -1
- package/dist/actions/extract.d.ts +0 -3
- package/dist/actions/extract.d.ts.map +0 -1
- package/dist/actions/extract.js +0 -168
- package/dist/actions/extract.js.map +0 -1
- package/dist/actions/index.d.ts +0 -7
- package/dist/actions/index.d.ts.map +0 -1
- package/dist/actions/index.js +0 -7
- package/dist/actions/index.js.map +0 -1
- package/dist/actions/navigate.d.ts +0 -3
- package/dist/actions/navigate.d.ts.map +0 -1
- package/dist/actions/navigate.js +0 -187
- package/dist/actions/navigate.js.map +0 -1
- package/dist/actions/screenshot.d.ts +0 -3
- package/dist/actions/screenshot.d.ts.map +0 -1
- package/dist/actions/screenshot.js +0 -167
- package/dist/actions/screenshot.js.map +0 -1
- package/dist/actions/select.d.ts +0 -3
- package/dist/actions/select.d.ts.map +0 -1
- package/dist/actions/select.js +0 -167
- package/dist/actions/select.js.map +0 -1
- package/dist/actions/type.d.ts +0 -3
- package/dist/actions/type.d.ts.map +0 -1
- package/dist/actions/type.js +0 -167
- package/dist/actions/type.js.map +0 -1
- package/dist/cli/index.d.ts +0 -8
- package/dist/cli/index.d.ts.map +0 -1
- package/dist/cli/index.js +0 -13
- package/dist/cli/index.js.map +0 -1
- package/dist/cli/register.d.ts +0 -20
- package/dist/cli/register.d.ts.map +0 -1
- package/dist/cli/register.js +0 -403
- package/dist/cli/register.js.map +0 -1
- package/dist/providerRelevance.d.ts +0 -4
- package/dist/providerRelevance.d.ts.map +0 -1
- package/dist/providerRelevance.js +0 -33
- package/dist/providerRelevance.js.map +0 -1
- package/dist/providers/browser-state.d.ts +0 -3
- package/dist/providers/browser-state.d.ts.map +0 -1
- package/dist/providers/browser-state.js +0 -72
- package/dist/providers/browser-state.js.map +0 -1
- package/dist/providers/index.d.ts +0 -2
- package/dist/providers/index.d.ts.map +0 -1
- package/dist/providers/index.js +0 -2
- package/dist/providers/index.js.map +0 -1
- package/dist/services/browser-service.d.ts +0 -32
- package/dist/services/browser-service.d.ts.map +0 -1
- package/dist/services/browser-service.js +0 -213
- package/dist/services/browser-service.js.map +0 -1
- package/dist/services/index.d.ts +0 -4
- package/dist/services/index.d.ts.map +0 -1
- package/dist/services/index.js +0 -4
- package/dist/services/index.js.map +0 -1
- package/dist/services/process-manager.d.ts +0 -24
- package/dist/services/process-manager.d.ts.map +0 -1
- package/dist/services/process-manager.js +0 -270
- package/dist/services/process-manager.js.map +0 -1
- package/dist/services/websocket-client.d.ts +0 -35
- package/dist/services/websocket-client.d.ts.map +0 -1
- package/dist/services/websocket-client.js +0 -221
- package/dist/services/websocket-client.js.map +0 -1
- package/dist/types.d.ts +0 -101
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -2
- package/dist/types.js.map +0 -1
- package/dist/utils/captcha.d.ts +0 -33
- package/dist/utils/captcha.d.ts.map +0 -1
- package/dist/utils/captcha.js +0 -219
- package/dist/utils/captcha.js.map +0 -1
- package/dist/utils/errors.d.ts +0 -37
- package/dist/utils/errors.d.ts.map +0 -1
- package/dist/utils/errors.js +0 -81
- package/dist/utils/errors.js.map +0 -1
- package/dist/utils/index.d.ts +0 -5
- package/dist/utils/index.d.ts.map +0 -1
- package/dist/utils/index.js +0 -5
- package/dist/utils/index.js.map +0 -1
- package/dist/utils/retry.d.ts +0 -26
- package/dist/utils/retry.d.ts.map +0 -1
- package/dist/utils/retry.js +0 -55
- package/dist/utils/retry.js.map +0 -1
- package/dist/utils/security.d.ts +0 -27
- package/dist/utils/security.d.ts.map +0 -1
- package/dist/utils/security.js +0 -139
- package/dist/utils/security.js.map +0 -1
- package/dist/utils/url.d.ts +0 -12
- package/dist/utils/url.d.ts.map +0 -1
- package/dist/utils/url.js +0 -39
- package/dist/utils/url.js.map +0 -1
|
@@ -0,0 +1,958 @@
|
|
|
1
|
+
import * as fsp from "node:fs/promises";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import { BROWSER_WORKSPACE_CONNECTOR_AUTH_STATES } from "./browser-workspace-types.js";
|
|
4
|
+
import { __resetBrowserWorkspaceStateForTests } from "./browser-workspace-state.js";
|
|
5
|
+
import {
|
|
6
|
+
evaluateBrowserWorkspaceTab as evaluateBrowserWorkspaceTabDesktop,
|
|
7
|
+
executeDesktopBrowserWorkspaceDomCommand,
|
|
8
|
+
executeDesktopBrowserWorkspaceUtilityCommand,
|
|
9
|
+
getBrowserWorkspaceUnavailableMessage,
|
|
10
|
+
getDesktopBrowserWorkspaceSessionState,
|
|
11
|
+
getDesktopBrowserWorkspaceSnapshotRecord,
|
|
12
|
+
isBrowserWorkspaceBridgeConfigured,
|
|
13
|
+
loadDesktopBrowserWorkspaceSessionState,
|
|
14
|
+
requestBrowserWorkspace,
|
|
15
|
+
resolveBrowserWorkspaceBridgeConfig,
|
|
16
|
+
resolveDesktopBrowserWorkspaceTargetTabId,
|
|
17
|
+
snapshotBrowserWorkspaceTab as snapshotBrowserWorkspaceTabDesktop
|
|
18
|
+
} from "./browser-workspace-desktop.js";
|
|
19
|
+
import {
|
|
20
|
+
assertBrowserWorkspaceConnectorSecretsNotExported,
|
|
21
|
+
assertBrowserWorkspaceUrl,
|
|
22
|
+
assertBrowserWorkspaceUserScriptAllowed,
|
|
23
|
+
createBrowserWorkspaceNotFoundError,
|
|
24
|
+
DEFAULT_WEB_PARTITION,
|
|
25
|
+
inferBrowserWorkspaceTitle,
|
|
26
|
+
normalizeBrowserWorkspaceCommand,
|
|
27
|
+
resolveBrowserWorkspaceCommandPartition,
|
|
28
|
+
resolveConnectorBrowserWorkspacePartition,
|
|
29
|
+
sleep,
|
|
30
|
+
writeBrowserWorkspaceFile
|
|
31
|
+
} from "./browser-workspace-helpers.js";
|
|
32
|
+
import {
|
|
33
|
+
clearWebBrowserWorkspaceTabElementRefs,
|
|
34
|
+
cloneWebBrowserWorkspaceTabState,
|
|
35
|
+
loadWebBrowserWorkspaceTabDocument,
|
|
36
|
+
pushWebBrowserWorkspaceHistory
|
|
37
|
+
} from "./browser-workspace-forms.js";
|
|
38
|
+
import { browserWorkspacePageFetch } from "./browser-workspace-helpers.js";
|
|
39
|
+
import {
|
|
40
|
+
createEmptyWebBrowserWorkspaceDom,
|
|
41
|
+
installBrowserWorkspaceWebRuntime
|
|
42
|
+
} from "./browser-workspace-jsdom.js";
|
|
43
|
+
import {
|
|
44
|
+
createBrowserWorkspacePdfBuffer,
|
|
45
|
+
createBrowserWorkspaceSnapshotRecord,
|
|
46
|
+
diffBrowserWorkspaceSnapshots
|
|
47
|
+
} from "./browser-workspace-snapshots.js";
|
|
48
|
+
import {
|
|
49
|
+
clearBrowserWorkspaceElementRefs,
|
|
50
|
+
clearBrowserWorkspaceRuntimeState,
|
|
51
|
+
getBrowserWorkspaceRuntimeState,
|
|
52
|
+
getBrowserWorkspaceTimestamp,
|
|
53
|
+
resetBrowserWorkspaceRuntimeNavigationState,
|
|
54
|
+
webWorkspaceState,
|
|
55
|
+
withWebStateLock
|
|
56
|
+
} from "./browser-workspace-state.js";
|
|
57
|
+
import {
|
|
58
|
+
executeWebBrowserWorkspaceDomCommand,
|
|
59
|
+
executeWebBrowserWorkspaceUtilityCommand,
|
|
60
|
+
findWebBrowserWorkspaceTargetTabId,
|
|
61
|
+
getWebBrowserWorkspaceTabIndex,
|
|
62
|
+
getWebBrowserWorkspaceTabState
|
|
63
|
+
} from "./browser-workspace-web.js";
|
|
64
|
+
const AGENT_BROWSER_WORKSPACE_PARTITION = "persist:eliza-browser-agent";
|
|
65
|
+
const CONNECTOR_MANUAL_STATES = /* @__PURE__ */ new Set([
|
|
66
|
+
"auth_pending",
|
|
67
|
+
"needs_reauth",
|
|
68
|
+
"manual_handoff"
|
|
69
|
+
]);
|
|
70
|
+
function getBrowserWorkspaceMode(env = process.env) {
|
|
71
|
+
return isBrowserWorkspaceBridgeConfigured(env) ? "desktop" : "web";
|
|
72
|
+
}
|
|
73
|
+
function resolveBrowserWorkspaceConnectorPartition(provider, accountId) {
|
|
74
|
+
return resolveConnectorBrowserWorkspacePartition(provider, accountId);
|
|
75
|
+
}
|
|
76
|
+
function normalizeConnectorAuthState(value, fallback) {
|
|
77
|
+
switch (value) {
|
|
78
|
+
case "unknown":
|
|
79
|
+
case "ready":
|
|
80
|
+
case "auth_pending":
|
|
81
|
+
case "needs_reauth":
|
|
82
|
+
case "manual_handoff":
|
|
83
|
+
return value;
|
|
84
|
+
default:
|
|
85
|
+
return fallback;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
function connectorSessionRequiresManualHandoff(state) {
|
|
89
|
+
return CONNECTOR_MANUAL_STATES.has(state);
|
|
90
|
+
}
|
|
91
|
+
function createConnectorSessionRef(ref) {
|
|
92
|
+
return {
|
|
93
|
+
kind: ref.kind,
|
|
94
|
+
handleId: ref.handleId,
|
|
95
|
+
partition: ref.partition,
|
|
96
|
+
tabId: ref.tabId,
|
|
97
|
+
browser: ref.browser,
|
|
98
|
+
companionId: ref.companionId,
|
|
99
|
+
profileId: ref.profileId,
|
|
100
|
+
profileLabel: ref.profileLabel
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
function createConnectorSessionHandle(args) {
|
|
104
|
+
const sessionRef = createConnectorSessionRef(args.ref);
|
|
105
|
+
return {
|
|
106
|
+
provider: args.provider,
|
|
107
|
+
accountId: args.accountId,
|
|
108
|
+
authState: args.authState,
|
|
109
|
+
requiresManualHandoff: connectorSessionRequiresManualHandoff(
|
|
110
|
+
args.authState
|
|
111
|
+
),
|
|
112
|
+
sessionRef,
|
|
113
|
+
partition: sessionRef.partition,
|
|
114
|
+
tabId: sessionRef.tabId,
|
|
115
|
+
companionId: sessionRef.companionId,
|
|
116
|
+
browser: sessionRef.browser,
|
|
117
|
+
profileId: sessionRef.profileId,
|
|
118
|
+
profileLabel: sessionRef.profileLabel,
|
|
119
|
+
created: args.created,
|
|
120
|
+
message: args.message ?? null
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
function createBrowserBridgeConnectorSessionHandle(args) {
|
|
124
|
+
const browser = args.companion.browser?.trim() || null;
|
|
125
|
+
const companionId = args.companion.companionId?.trim() || null;
|
|
126
|
+
const profileId = args.companion.profileId?.trim() || null;
|
|
127
|
+
const profileLabel = args.companion.profileLabel?.trim() || null;
|
|
128
|
+
return createConnectorSessionHandle({
|
|
129
|
+
provider: args.provider,
|
|
130
|
+
accountId: args.accountId,
|
|
131
|
+
authState: args.authState,
|
|
132
|
+
created: false,
|
|
133
|
+
message: args.message,
|
|
134
|
+
ref: {
|
|
135
|
+
kind: "browser-bridge-companion",
|
|
136
|
+
handleId: [
|
|
137
|
+
"browser-bridge",
|
|
138
|
+
browser ?? "browser",
|
|
139
|
+
companionId ?? profileId ?? "profile",
|
|
140
|
+
args.provider,
|
|
141
|
+
args.accountId
|
|
142
|
+
].join(":"),
|
|
143
|
+
partition: null,
|
|
144
|
+
tabId: null,
|
|
145
|
+
browser,
|
|
146
|
+
companionId,
|
|
147
|
+
profileId,
|
|
148
|
+
profileLabel
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
async function assertDesktopBrowserWorkspaceCanAccessProfileSecrets(command, env, operation) {
|
|
153
|
+
const id = await resolveDesktopBrowserWorkspaceTargetTabId(command, env);
|
|
154
|
+
const tabs = await listBrowserWorkspaceTabs(env);
|
|
155
|
+
const tab = tabs.find((entry) => entry.id === id) ?? null;
|
|
156
|
+
assertBrowserWorkspaceConnectorSecretsNotExported(tab?.partition, operation);
|
|
157
|
+
}
|
|
158
|
+
async function acquireBrowserWorkspaceConnectorSession(request, env = process.env) {
|
|
159
|
+
const provider = request.provider.trim();
|
|
160
|
+
const accountId = request.accountId.trim();
|
|
161
|
+
if (!provider) {
|
|
162
|
+
throw new Error("Eliza browser connector session requires provider.");
|
|
163
|
+
}
|
|
164
|
+
if (!accountId) {
|
|
165
|
+
throw new Error("Eliza browser connector session requires accountId.");
|
|
166
|
+
}
|
|
167
|
+
const companion = request.companion ?? null;
|
|
168
|
+
if (companion?.profileId || companion?.companionId) {
|
|
169
|
+
const authState2 = normalizeConnectorAuthState(
|
|
170
|
+
request.authState,
|
|
171
|
+
"manual_handoff"
|
|
172
|
+
);
|
|
173
|
+
return createBrowserBridgeConnectorSessionHandle({
|
|
174
|
+
provider,
|
|
175
|
+
accountId,
|
|
176
|
+
companion,
|
|
177
|
+
authState: authState2,
|
|
178
|
+
message: request.manualHandoffReason ?? "Use the paired browser companion profile to finish login, MFA, or CAPTCHA if required."
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
if (isBrowserWorkspaceBridgeConfigured(env)) {
|
|
182
|
+
const payload = await requestBrowserWorkspace(
|
|
183
|
+
"/sessions/acquire",
|
|
184
|
+
{
|
|
185
|
+
method: "POST",
|
|
186
|
+
body: JSON.stringify({
|
|
187
|
+
accountId,
|
|
188
|
+
authState: request.authState,
|
|
189
|
+
manualHandoffReason: request.manualHandoffReason,
|
|
190
|
+
provider,
|
|
191
|
+
reuse: request.reuse,
|
|
192
|
+
show: request.show,
|
|
193
|
+
title: request.title,
|
|
194
|
+
url: request.url
|
|
195
|
+
})
|
|
196
|
+
},
|
|
197
|
+
env
|
|
198
|
+
);
|
|
199
|
+
return payload.session;
|
|
200
|
+
}
|
|
201
|
+
const partition = resolveBrowserWorkspaceConnectorPartition(
|
|
202
|
+
provider,
|
|
203
|
+
accountId
|
|
204
|
+
);
|
|
205
|
+
const reuse = request.reuse !== false;
|
|
206
|
+
const tabs = reuse ? await listBrowserWorkspaceTabs(env) : [];
|
|
207
|
+
const existing = tabs.find((tab2) => tab2.partition === partition) ?? null;
|
|
208
|
+
let tab = existing;
|
|
209
|
+
let created = false;
|
|
210
|
+
if (!tab) {
|
|
211
|
+
tab = await openBrowserWorkspaceTab(
|
|
212
|
+
{
|
|
213
|
+
kind: "internal",
|
|
214
|
+
partition,
|
|
215
|
+
show: request.show ?? true,
|
|
216
|
+
title: request.title,
|
|
217
|
+
url: request.url
|
|
218
|
+
},
|
|
219
|
+
env
|
|
220
|
+
);
|
|
221
|
+
created = true;
|
|
222
|
+
} else if (request.show === true) {
|
|
223
|
+
tab = await showBrowserWorkspaceTab(tab.id, env);
|
|
224
|
+
}
|
|
225
|
+
const authState = normalizeConnectorAuthState(
|
|
226
|
+
request.authState,
|
|
227
|
+
created ? "auth_pending" : "ready"
|
|
228
|
+
);
|
|
229
|
+
return createConnectorSessionHandle({
|
|
230
|
+
provider,
|
|
231
|
+
accountId,
|
|
232
|
+
authState,
|
|
233
|
+
created,
|
|
234
|
+
message: request.manualHandoffReason ?? (connectorSessionRequiresManualHandoff(authState) ? "Manual login, MFA, or CAPTCHA may be required in this isolated connector browser session." : null),
|
|
235
|
+
ref: {
|
|
236
|
+
kind: "internal-browser",
|
|
237
|
+
handleId: `internal-browser:${partition}`,
|
|
238
|
+
partition,
|
|
239
|
+
tabId: tab.id,
|
|
240
|
+
browser: null,
|
|
241
|
+
companionId: null,
|
|
242
|
+
profileId: null,
|
|
243
|
+
profileLabel: null
|
|
244
|
+
}
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
async function getBrowserWorkspaceSnapshot(env = process.env) {
|
|
248
|
+
return {
|
|
249
|
+
mode: getBrowserWorkspaceMode(env),
|
|
250
|
+
tabs: await listBrowserWorkspaceTabs(env)
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
async function listBrowserWorkspaceTabs(env = process.env) {
|
|
254
|
+
if (!isBrowserWorkspaceBridgeConfigured(env)) {
|
|
255
|
+
return webWorkspaceState.tabs.map((tab) => ({
|
|
256
|
+
id: tab.id,
|
|
257
|
+
title: tab.title,
|
|
258
|
+
url: tab.url,
|
|
259
|
+
partition: tab.partition,
|
|
260
|
+
kind: tab.kind,
|
|
261
|
+
visible: tab.visible,
|
|
262
|
+
createdAt: tab.createdAt,
|
|
263
|
+
updatedAt: tab.updatedAt,
|
|
264
|
+
lastFocusedAt: tab.lastFocusedAt
|
|
265
|
+
}));
|
|
266
|
+
}
|
|
267
|
+
const payload = await requestBrowserWorkspace("/tabs", void 0, env);
|
|
268
|
+
return Array.isArray(payload.tabs) ? payload.tabs : [];
|
|
269
|
+
}
|
|
270
|
+
async function openBrowserWorkspaceTab(request, env = process.env) {
|
|
271
|
+
if (!isBrowserWorkspaceBridgeConfigured(env)) {
|
|
272
|
+
return withWebStateLock(() => {
|
|
273
|
+
const kind = request.kind === "internal" ? "internal" : "standard";
|
|
274
|
+
const now = getBrowserWorkspaceTimestamp();
|
|
275
|
+
const url = assertBrowserWorkspaceUrl(
|
|
276
|
+
request.url?.trim() || "about:blank"
|
|
277
|
+
);
|
|
278
|
+
const visible = request.show === true;
|
|
279
|
+
const id = `btab_${webWorkspaceState.nextId++}`;
|
|
280
|
+
const dom = url === "about:blank" ? createEmptyWebBrowserWorkspaceDom(url) : null;
|
|
281
|
+
const tab = {
|
|
282
|
+
id,
|
|
283
|
+
title: request.title?.trim() || inferBrowserWorkspaceTitle(url),
|
|
284
|
+
url,
|
|
285
|
+
partition: request.partition?.trim() || DEFAULT_WEB_PARTITION,
|
|
286
|
+
kind,
|
|
287
|
+
visible,
|
|
288
|
+
createdAt: now,
|
|
289
|
+
updatedAt: now,
|
|
290
|
+
lastFocusedAt: visible ? now : null,
|
|
291
|
+
dom,
|
|
292
|
+
history: [url],
|
|
293
|
+
historyIndex: 0,
|
|
294
|
+
loadedUrl: url === "about:blank" ? url : null
|
|
295
|
+
};
|
|
296
|
+
if (dom) {
|
|
297
|
+
installBrowserWorkspaceWebRuntime(tab, dom);
|
|
298
|
+
}
|
|
299
|
+
getBrowserWorkspaceRuntimeState("web", tab.id);
|
|
300
|
+
clearWebBrowserWorkspaceTabElementRefs(tab.id);
|
|
301
|
+
if (tab.visible) {
|
|
302
|
+
webWorkspaceState.tabs = webWorkspaceState.tabs.map((entry) => ({
|
|
303
|
+
...entry,
|
|
304
|
+
visible: false
|
|
305
|
+
}));
|
|
306
|
+
}
|
|
307
|
+
webWorkspaceState.tabs = [...webWorkspaceState.tabs, tab];
|
|
308
|
+
return cloneWebBrowserWorkspaceTabState(tab);
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
const payload = await requestBrowserWorkspace(
|
|
312
|
+
"/tabs",
|
|
313
|
+
{
|
|
314
|
+
method: "POST",
|
|
315
|
+
body: JSON.stringify(request)
|
|
316
|
+
},
|
|
317
|
+
env
|
|
318
|
+
);
|
|
319
|
+
return payload.tab;
|
|
320
|
+
}
|
|
321
|
+
async function navigateBrowserWorkspaceTab(request, env = process.env) {
|
|
322
|
+
const nextUrl = assertBrowserWorkspaceUrl(request.url);
|
|
323
|
+
if (!isBrowserWorkspaceBridgeConfigured(env)) {
|
|
324
|
+
return withWebStateLock(() => {
|
|
325
|
+
const index = getWebBrowserWorkspaceTabIndex(request.id);
|
|
326
|
+
if (index < 0) {
|
|
327
|
+
throw createBrowserWorkspaceNotFoundError(request.id);
|
|
328
|
+
}
|
|
329
|
+
const existing = webWorkspaceState.tabs[index];
|
|
330
|
+
const updatedAt = getBrowserWorkspaceTimestamp();
|
|
331
|
+
const state = getBrowserWorkspaceRuntimeState("web", existing.id);
|
|
332
|
+
clearWebBrowserWorkspaceTabElementRefs(existing.id);
|
|
333
|
+
pushWebBrowserWorkspaceHistory(existing, nextUrl);
|
|
334
|
+
const nextDom = nextUrl === "about:blank" ? createEmptyWebBrowserWorkspaceDom(nextUrl) : null;
|
|
335
|
+
const nextTab = {
|
|
336
|
+
...existing,
|
|
337
|
+
title: inferBrowserWorkspaceTitle(nextUrl),
|
|
338
|
+
url: nextUrl,
|
|
339
|
+
updatedAt,
|
|
340
|
+
dom: nextDom,
|
|
341
|
+
loadedUrl: nextUrl === "about:blank" ? nextUrl : null
|
|
342
|
+
};
|
|
343
|
+
if (nextDom) {
|
|
344
|
+
installBrowserWorkspaceWebRuntime(nextTab, nextDom);
|
|
345
|
+
}
|
|
346
|
+
resetBrowserWorkspaceRuntimeNavigationState(state);
|
|
347
|
+
webWorkspaceState.tabs[index] = nextTab;
|
|
348
|
+
return cloneWebBrowserWorkspaceTabState(nextTab);
|
|
349
|
+
});
|
|
350
|
+
}
|
|
351
|
+
const navigateBody = { url: nextUrl };
|
|
352
|
+
if (request.partition !== void 0) {
|
|
353
|
+
navigateBody.partition = request.partition;
|
|
354
|
+
}
|
|
355
|
+
const payload = await requestBrowserWorkspace(
|
|
356
|
+
`/tabs/${encodeURIComponent(request.id)}/navigate`,
|
|
357
|
+
{
|
|
358
|
+
method: "POST",
|
|
359
|
+
body: JSON.stringify(navigateBody)
|
|
360
|
+
},
|
|
361
|
+
env
|
|
362
|
+
);
|
|
363
|
+
return payload.tab;
|
|
364
|
+
}
|
|
365
|
+
async function showBrowserWorkspaceTab(id, env = process.env) {
|
|
366
|
+
if (!isBrowserWorkspaceBridgeConfigured(env)) {
|
|
367
|
+
return withWebStateLock(() => {
|
|
368
|
+
getWebBrowserWorkspaceTabState(id);
|
|
369
|
+
const lastFocusedAt = getBrowserWorkspaceTimestamp();
|
|
370
|
+
webWorkspaceState.tabs = webWorkspaceState.tabs.map((tab) => ({
|
|
371
|
+
...tab,
|
|
372
|
+
visible: tab.id === id,
|
|
373
|
+
lastFocusedAt: tab.id === id ? lastFocusedAt : tab.lastFocusedAt,
|
|
374
|
+
updatedAt: tab.id === id ? lastFocusedAt : tab.updatedAt
|
|
375
|
+
}));
|
|
376
|
+
return cloneWebBrowserWorkspaceTabState(
|
|
377
|
+
getWebBrowserWorkspaceTabState(id)
|
|
378
|
+
);
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
const payload = await requestBrowserWorkspace(
|
|
382
|
+
`/tabs/${encodeURIComponent(id)}/show`,
|
|
383
|
+
{ method: "POST" },
|
|
384
|
+
env
|
|
385
|
+
);
|
|
386
|
+
return payload.tab;
|
|
387
|
+
}
|
|
388
|
+
async function hideBrowserWorkspaceTab(id, env = process.env) {
|
|
389
|
+
if (!isBrowserWorkspaceBridgeConfigured(env)) {
|
|
390
|
+
return withWebStateLock(() => {
|
|
391
|
+
const index = getWebBrowserWorkspaceTabIndex(id);
|
|
392
|
+
if (index < 0) {
|
|
393
|
+
throw createBrowserWorkspaceNotFoundError(id);
|
|
394
|
+
}
|
|
395
|
+
const updatedAt = getBrowserWorkspaceTimestamp();
|
|
396
|
+
const nextTab = {
|
|
397
|
+
...webWorkspaceState.tabs[index],
|
|
398
|
+
visible: false,
|
|
399
|
+
updatedAt
|
|
400
|
+
};
|
|
401
|
+
webWorkspaceState.tabs[index] = nextTab;
|
|
402
|
+
return cloneWebBrowserWorkspaceTabState(nextTab);
|
|
403
|
+
});
|
|
404
|
+
}
|
|
405
|
+
const payload = await requestBrowserWorkspace(
|
|
406
|
+
`/tabs/${encodeURIComponent(id)}/hide`,
|
|
407
|
+
{ method: "POST" },
|
|
408
|
+
env
|
|
409
|
+
);
|
|
410
|
+
return payload.tab;
|
|
411
|
+
}
|
|
412
|
+
async function closeBrowserWorkspaceTab(id, env = process.env) {
|
|
413
|
+
if (!isBrowserWorkspaceBridgeConfigured(env)) {
|
|
414
|
+
return withWebStateLock(() => {
|
|
415
|
+
const initialLength = webWorkspaceState.tabs.length;
|
|
416
|
+
clearWebBrowserWorkspaceTabElementRefs(id);
|
|
417
|
+
clearBrowserWorkspaceRuntimeState("web", id);
|
|
418
|
+
webWorkspaceState.tabs = webWorkspaceState.tabs.filter(
|
|
419
|
+
(tab) => tab.id !== id
|
|
420
|
+
);
|
|
421
|
+
return webWorkspaceState.tabs.length !== initialLength;
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
const payload = await requestBrowserWorkspace(
|
|
425
|
+
`/tabs/${encodeURIComponent(id)}`,
|
|
426
|
+
{ method: "DELETE" },
|
|
427
|
+
env
|
|
428
|
+
);
|
|
429
|
+
return payload.closed === true;
|
|
430
|
+
}
|
|
431
|
+
async function evaluateBrowserWorkspaceTab(request, env = process.env) {
|
|
432
|
+
return evaluateBrowserWorkspaceTabDesktop(request, env);
|
|
433
|
+
}
|
|
434
|
+
async function snapshotBrowserWorkspaceTab(id, env = process.env) {
|
|
435
|
+
return snapshotBrowserWorkspaceTabDesktop(id, env);
|
|
436
|
+
}
|
|
437
|
+
async function executeBrowserWorkspaceCommand(command, env = process.env) {
|
|
438
|
+
command = normalizeBrowserWorkspaceCommand(command);
|
|
439
|
+
switch (command.subaction) {
|
|
440
|
+
case "batch": {
|
|
441
|
+
const steps = Array.isArray(command.steps) ? command.steps : [];
|
|
442
|
+
if (steps.length === 0) {
|
|
443
|
+
throw new Error(
|
|
444
|
+
"Eliza browser workspace batch requires at least one step."
|
|
445
|
+
);
|
|
446
|
+
}
|
|
447
|
+
const results = [];
|
|
448
|
+
for (const step of steps) {
|
|
449
|
+
results.push(await executeBrowserWorkspaceCommand(step, env));
|
|
450
|
+
}
|
|
451
|
+
return {
|
|
452
|
+
mode: getBrowserWorkspaceMode(env),
|
|
453
|
+
subaction: command.subaction,
|
|
454
|
+
steps: results,
|
|
455
|
+
value: results.at(-1)?.value
|
|
456
|
+
};
|
|
457
|
+
}
|
|
458
|
+
case "list":
|
|
459
|
+
return {
|
|
460
|
+
mode: getBrowserWorkspaceMode(env),
|
|
461
|
+
subaction: command.subaction,
|
|
462
|
+
tabs: await listBrowserWorkspaceTabs(env)
|
|
463
|
+
};
|
|
464
|
+
case "open": {
|
|
465
|
+
const tab = await openBrowserWorkspaceTab(
|
|
466
|
+
{
|
|
467
|
+
partition: resolveBrowserWorkspaceCommandPartition(
|
|
468
|
+
command,
|
|
469
|
+
AGENT_BROWSER_WORKSPACE_PARTITION
|
|
470
|
+
),
|
|
471
|
+
show: command.show,
|
|
472
|
+
title: command.title,
|
|
473
|
+
url: command.url
|
|
474
|
+
},
|
|
475
|
+
env
|
|
476
|
+
);
|
|
477
|
+
clearBrowserWorkspaceElementRefs(getBrowserWorkspaceMode(env), tab.id);
|
|
478
|
+
return {
|
|
479
|
+
mode: getBrowserWorkspaceMode(env),
|
|
480
|
+
subaction: command.subaction,
|
|
481
|
+
tab
|
|
482
|
+
};
|
|
483
|
+
}
|
|
484
|
+
case "navigate": {
|
|
485
|
+
const id = isBrowserWorkspaceBridgeConfigured(env) ? await resolveDesktopBrowserWorkspaceTargetTabId(command, env) : findWebBrowserWorkspaceTargetTabId(command);
|
|
486
|
+
clearBrowserWorkspaceElementRefs(getBrowserWorkspaceMode(env), id);
|
|
487
|
+
return {
|
|
488
|
+
mode: getBrowserWorkspaceMode(env),
|
|
489
|
+
subaction: command.subaction,
|
|
490
|
+
tab: await navigateBrowserWorkspaceTab(
|
|
491
|
+
{
|
|
492
|
+
id,
|
|
493
|
+
url: command.url ?? ""
|
|
494
|
+
},
|
|
495
|
+
env
|
|
496
|
+
)
|
|
497
|
+
};
|
|
498
|
+
}
|
|
499
|
+
case "show": {
|
|
500
|
+
const id = isBrowserWorkspaceBridgeConfigured(env) ? await resolveDesktopBrowserWorkspaceTargetTabId(command, env) : findWebBrowserWorkspaceTargetTabId(command);
|
|
501
|
+
return {
|
|
502
|
+
mode: getBrowserWorkspaceMode(env),
|
|
503
|
+
subaction: command.subaction,
|
|
504
|
+
tab: await showBrowserWorkspaceTab(id, env)
|
|
505
|
+
};
|
|
506
|
+
}
|
|
507
|
+
case "hide": {
|
|
508
|
+
const id = isBrowserWorkspaceBridgeConfigured(env) ? await resolveDesktopBrowserWorkspaceTargetTabId(command, env) : findWebBrowserWorkspaceTargetTabId(command);
|
|
509
|
+
return {
|
|
510
|
+
mode: getBrowserWorkspaceMode(env),
|
|
511
|
+
subaction: command.subaction,
|
|
512
|
+
tab: await hideBrowserWorkspaceTab(id, env)
|
|
513
|
+
};
|
|
514
|
+
}
|
|
515
|
+
case "close": {
|
|
516
|
+
const id = isBrowserWorkspaceBridgeConfigured(env) ? await resolveDesktopBrowserWorkspaceTargetTabId(command, env) : findWebBrowserWorkspaceTargetTabId(command);
|
|
517
|
+
clearBrowserWorkspaceElementRefs(getBrowserWorkspaceMode(env), id);
|
|
518
|
+
clearBrowserWorkspaceRuntimeState(getBrowserWorkspaceMode(env), id);
|
|
519
|
+
return {
|
|
520
|
+
mode: getBrowserWorkspaceMode(env),
|
|
521
|
+
subaction: command.subaction,
|
|
522
|
+
closed: await closeBrowserWorkspaceTab(id, env)
|
|
523
|
+
};
|
|
524
|
+
}
|
|
525
|
+
case "eval": {
|
|
526
|
+
if (!isBrowserWorkspaceBridgeConfigured(env)) {
|
|
527
|
+
return await executeWebBrowserWorkspaceUtilityCommand(
|
|
528
|
+
command
|
|
529
|
+
);
|
|
530
|
+
}
|
|
531
|
+
assertBrowserWorkspaceUserScriptAllowed(
|
|
532
|
+
command.script,
|
|
533
|
+
"eval",
|
|
534
|
+
"desktop",
|
|
535
|
+
env
|
|
536
|
+
);
|
|
537
|
+
const id = await resolveDesktopBrowserWorkspaceTargetTabId(command, env);
|
|
538
|
+
return {
|
|
539
|
+
mode: "desktop",
|
|
540
|
+
subaction: command.subaction,
|
|
541
|
+
value: await evaluateBrowserWorkspaceTab(
|
|
542
|
+
{
|
|
543
|
+
id,
|
|
544
|
+
script: command.script ?? ""
|
|
545
|
+
},
|
|
546
|
+
env
|
|
547
|
+
)
|
|
548
|
+
};
|
|
549
|
+
}
|
|
550
|
+
case "screenshot": {
|
|
551
|
+
if (!isBrowserWorkspaceBridgeConfigured(env)) {
|
|
552
|
+
return await executeWebBrowserWorkspaceUtilityCommand(
|
|
553
|
+
command
|
|
554
|
+
);
|
|
555
|
+
}
|
|
556
|
+
const id = await resolveDesktopBrowserWorkspaceTargetTabId(command, env);
|
|
557
|
+
return {
|
|
558
|
+
mode: "desktop",
|
|
559
|
+
subaction: command.subaction,
|
|
560
|
+
snapshot: await snapshotBrowserWorkspaceTab(id, env)
|
|
561
|
+
};
|
|
562
|
+
}
|
|
563
|
+
case "clipboard":
|
|
564
|
+
case "console":
|
|
565
|
+
case "cookies":
|
|
566
|
+
case "dialog":
|
|
567
|
+
case "drag":
|
|
568
|
+
case "errors":
|
|
569
|
+
case "frame":
|
|
570
|
+
case "highlight":
|
|
571
|
+
case "mouse":
|
|
572
|
+
case "network":
|
|
573
|
+
case "set":
|
|
574
|
+
case "storage":
|
|
575
|
+
case "upload": {
|
|
576
|
+
if (!isBrowserWorkspaceBridgeConfigured(env)) {
|
|
577
|
+
return await executeWebBrowserWorkspaceUtilityCommand(
|
|
578
|
+
command
|
|
579
|
+
);
|
|
580
|
+
}
|
|
581
|
+
return executeDesktopBrowserWorkspaceUtilityCommand(command, env);
|
|
582
|
+
}
|
|
583
|
+
case "diff": {
|
|
584
|
+
if (!isBrowserWorkspaceBridgeConfigured(env)) {
|
|
585
|
+
return await executeWebBrowserWorkspaceUtilityCommand(
|
|
586
|
+
command
|
|
587
|
+
);
|
|
588
|
+
}
|
|
589
|
+
const id = await resolveDesktopBrowserWorkspaceTargetTabId(command, env);
|
|
590
|
+
const runtime = getBrowserWorkspaceRuntimeState("desktop", id);
|
|
591
|
+
const snapshot = await getDesktopBrowserWorkspaceSnapshotRecord(
|
|
592
|
+
command,
|
|
593
|
+
env
|
|
594
|
+
);
|
|
595
|
+
if (command.diffAction === "screenshot") {
|
|
596
|
+
const screenshot = await snapshotBrowserWorkspaceTab(id, env);
|
|
597
|
+
const currentData = screenshot.data;
|
|
598
|
+
const baseline2 = command.baselinePath?.trim() ? await fsp.readFile(
|
|
599
|
+
path.resolve(command.baselinePath.trim()),
|
|
600
|
+
"base64"
|
|
601
|
+
) : runtime.lastScreenshotData;
|
|
602
|
+
runtime.lastScreenshotData = currentData;
|
|
603
|
+
return {
|
|
604
|
+
mode: "desktop",
|
|
605
|
+
subaction: command.subaction,
|
|
606
|
+
value: {
|
|
607
|
+
baselineLength: baseline2?.length ?? 0,
|
|
608
|
+
changed: baseline2 !== currentData,
|
|
609
|
+
currentLength: currentData.length
|
|
610
|
+
}
|
|
611
|
+
};
|
|
612
|
+
}
|
|
613
|
+
if (command.diffAction === "url") {
|
|
614
|
+
const leftUrl = command.url?.trim() || snapshot.url;
|
|
615
|
+
const rightUrl = command.secondaryUrl?.trim();
|
|
616
|
+
if (!rightUrl) {
|
|
617
|
+
throw new Error(
|
|
618
|
+
"Eliza browser workspace diff url requires secondaryUrl."
|
|
619
|
+
);
|
|
620
|
+
}
|
|
621
|
+
const left = await browserWorkspacePageFetch(leftUrl);
|
|
622
|
+
const right = await browserWorkspacePageFetch(rightUrl);
|
|
623
|
+
return {
|
|
624
|
+
mode: "desktop",
|
|
625
|
+
subaction: command.subaction,
|
|
626
|
+
value: diffBrowserWorkspaceSnapshots(
|
|
627
|
+
createBrowserWorkspaceSnapshotRecord(
|
|
628
|
+
leftUrl,
|
|
629
|
+
left.url || leftUrl,
|
|
630
|
+
await left.text()
|
|
631
|
+
),
|
|
632
|
+
createBrowserWorkspaceSnapshotRecord(
|
|
633
|
+
rightUrl,
|
|
634
|
+
right.url || rightUrl,
|
|
635
|
+
await right.text()
|
|
636
|
+
)
|
|
637
|
+
)
|
|
638
|
+
};
|
|
639
|
+
}
|
|
640
|
+
const baseline = command.baselinePath?.trim() ? JSON.parse(
|
|
641
|
+
await fsp.readFile(
|
|
642
|
+
path.resolve(command.baselinePath.trim()),
|
|
643
|
+
"utf8"
|
|
644
|
+
)
|
|
645
|
+
) : runtime.lastSnapshot;
|
|
646
|
+
const diff = diffBrowserWorkspaceSnapshots(baseline, snapshot);
|
|
647
|
+
runtime.lastSnapshot = snapshot;
|
|
648
|
+
return { mode: "desktop", subaction: command.subaction, value: diff };
|
|
649
|
+
}
|
|
650
|
+
case "trace":
|
|
651
|
+
case "profiler": {
|
|
652
|
+
if (!isBrowserWorkspaceBridgeConfigured(env)) {
|
|
653
|
+
return await executeWebBrowserWorkspaceUtilityCommand(
|
|
654
|
+
command
|
|
655
|
+
);
|
|
656
|
+
}
|
|
657
|
+
const id = await resolveDesktopBrowserWorkspaceTargetTabId(command, env);
|
|
658
|
+
const runtime = getBrowserWorkspaceRuntimeState("desktop", id);
|
|
659
|
+
const target = command.subaction === "trace" ? runtime.trace : runtime.profiler;
|
|
660
|
+
const stop = command.subaction === "trace" ? command.traceAction === "stop" : command.profilerAction === "stop";
|
|
661
|
+
if (stop) {
|
|
662
|
+
target.active = false;
|
|
663
|
+
const payload = { entries: target.entries };
|
|
664
|
+
const filePath = command.filePath?.trim() || command.outputPath?.trim();
|
|
665
|
+
if (filePath) {
|
|
666
|
+
await writeBrowserWorkspaceFile(
|
|
667
|
+
filePath,
|
|
668
|
+
JSON.stringify(payload, null, 2)
|
|
669
|
+
);
|
|
670
|
+
return {
|
|
671
|
+
mode: "desktop",
|
|
672
|
+
subaction: command.subaction,
|
|
673
|
+
value: { path: path.resolve(filePath), ...payload }
|
|
674
|
+
};
|
|
675
|
+
}
|
|
676
|
+
return {
|
|
677
|
+
mode: "desktop",
|
|
678
|
+
subaction: command.subaction,
|
|
679
|
+
value: payload
|
|
680
|
+
};
|
|
681
|
+
}
|
|
682
|
+
target.active = true;
|
|
683
|
+
target.entries = [
|
|
684
|
+
{
|
|
685
|
+
command: `${command.subaction}:start`,
|
|
686
|
+
timestamp: getBrowserWorkspaceTimestamp()
|
|
687
|
+
}
|
|
688
|
+
];
|
|
689
|
+
return {
|
|
690
|
+
mode: "desktop",
|
|
691
|
+
subaction: command.subaction,
|
|
692
|
+
value: { active: true }
|
|
693
|
+
};
|
|
694
|
+
}
|
|
695
|
+
case "state": {
|
|
696
|
+
if (!isBrowserWorkspaceBridgeConfigured(env)) {
|
|
697
|
+
return await executeWebBrowserWorkspaceUtilityCommand(
|
|
698
|
+
command
|
|
699
|
+
);
|
|
700
|
+
}
|
|
701
|
+
await assertDesktopBrowserWorkspaceCanAccessProfileSecrets(
|
|
702
|
+
command,
|
|
703
|
+
env,
|
|
704
|
+
"state"
|
|
705
|
+
);
|
|
706
|
+
if (command.stateAction === "load") {
|
|
707
|
+
const filePath2 = command.filePath?.trim() || command.outputPath?.trim();
|
|
708
|
+
if (!filePath2) {
|
|
709
|
+
throw new Error(
|
|
710
|
+
"Eliza browser workspace state load requires filePath."
|
|
711
|
+
);
|
|
712
|
+
}
|
|
713
|
+
const payload2 = JSON.parse(
|
|
714
|
+
await fsp.readFile(path.resolve(filePath2), "utf8")
|
|
715
|
+
);
|
|
716
|
+
await loadDesktopBrowserWorkspaceSessionState(command, payload2, env);
|
|
717
|
+
return {
|
|
718
|
+
mode: "desktop",
|
|
719
|
+
subaction: command.subaction,
|
|
720
|
+
value: { loaded: true }
|
|
721
|
+
};
|
|
722
|
+
}
|
|
723
|
+
const payload = await getDesktopBrowserWorkspaceSessionState(
|
|
724
|
+
command,
|
|
725
|
+
env
|
|
726
|
+
);
|
|
727
|
+
const filePath = command.filePath?.trim() || command.outputPath?.trim();
|
|
728
|
+
if (filePath) {
|
|
729
|
+
await writeBrowserWorkspaceFile(
|
|
730
|
+
filePath,
|
|
731
|
+
JSON.stringify(payload, null, 2)
|
|
732
|
+
);
|
|
733
|
+
return {
|
|
734
|
+
mode: "desktop",
|
|
735
|
+
subaction: command.subaction,
|
|
736
|
+
value: { path: path.resolve(filePath), ...payload }
|
|
737
|
+
};
|
|
738
|
+
}
|
|
739
|
+
return { mode: "desktop", subaction: command.subaction, value: payload };
|
|
740
|
+
}
|
|
741
|
+
case "pdf": {
|
|
742
|
+
if (!isBrowserWorkspaceBridgeConfigured(env)) {
|
|
743
|
+
return await executeWebBrowserWorkspaceUtilityCommand(
|
|
744
|
+
command
|
|
745
|
+
);
|
|
746
|
+
}
|
|
747
|
+
const filePath = command.filePath?.trim() || command.outputPath?.trim();
|
|
748
|
+
if (!filePath) {
|
|
749
|
+
throw new Error("Eliza browser workspace pdf requires filePath.");
|
|
750
|
+
}
|
|
751
|
+
const snapshot = await getDesktopBrowserWorkspaceSnapshotRecord(
|
|
752
|
+
command,
|
|
753
|
+
env
|
|
754
|
+
);
|
|
755
|
+
const pdf = createBrowserWorkspacePdfBuffer(
|
|
756
|
+
snapshot.title,
|
|
757
|
+
snapshot.bodyText
|
|
758
|
+
);
|
|
759
|
+
const resolved = await writeBrowserWorkspaceFile(filePath, pdf);
|
|
760
|
+
return {
|
|
761
|
+
mode: "desktop",
|
|
762
|
+
subaction: command.subaction,
|
|
763
|
+
value: { path: resolved, size: pdf.byteLength }
|
|
764
|
+
};
|
|
765
|
+
}
|
|
766
|
+
case "tab": {
|
|
767
|
+
const action = command.tabAction ?? "list";
|
|
768
|
+
if (action === "list") {
|
|
769
|
+
return {
|
|
770
|
+
mode: getBrowserWorkspaceMode(env),
|
|
771
|
+
subaction: command.subaction,
|
|
772
|
+
tabs: await listBrowserWorkspaceTabs(env)
|
|
773
|
+
};
|
|
774
|
+
}
|
|
775
|
+
if (action === "new") {
|
|
776
|
+
return {
|
|
777
|
+
mode: getBrowserWorkspaceMode(env),
|
|
778
|
+
subaction: command.subaction,
|
|
779
|
+
tab: await openBrowserWorkspaceTab(
|
|
780
|
+
{
|
|
781
|
+
partition: resolveBrowserWorkspaceCommandPartition(
|
|
782
|
+
command,
|
|
783
|
+
AGENT_BROWSER_WORKSPACE_PARTITION
|
|
784
|
+
),
|
|
785
|
+
show: command.show ?? true,
|
|
786
|
+
title: command.title,
|
|
787
|
+
url: command.url,
|
|
788
|
+
width: command.width,
|
|
789
|
+
height: command.height
|
|
790
|
+
},
|
|
791
|
+
env
|
|
792
|
+
)
|
|
793
|
+
};
|
|
794
|
+
}
|
|
795
|
+
if (action === "switch") {
|
|
796
|
+
const tabs = await listBrowserWorkspaceTabs(env);
|
|
797
|
+
const target = command.id?.trim() ? tabs.find((tab) => tab.id === command.id?.trim()) : typeof command.index === "number" ? tabs[command.index] ?? null : null;
|
|
798
|
+
if (!target) {
|
|
799
|
+
throw new Error(
|
|
800
|
+
"Eliza browser workspace tab switch requires a valid id or index."
|
|
801
|
+
);
|
|
802
|
+
}
|
|
803
|
+
return {
|
|
804
|
+
mode: getBrowserWorkspaceMode(env),
|
|
805
|
+
subaction: command.subaction,
|
|
806
|
+
tab: await showBrowserWorkspaceTab(target.id, env)
|
|
807
|
+
};
|
|
808
|
+
}
|
|
809
|
+
const targetId = command.id?.trim() || (await listBrowserWorkspaceTabs(env))[command.index ?? -1]?.id;
|
|
810
|
+
if (!targetId) {
|
|
811
|
+
throw new Error(
|
|
812
|
+
"Eliza browser workspace tab close requires a valid id or index."
|
|
813
|
+
);
|
|
814
|
+
}
|
|
815
|
+
return {
|
|
816
|
+
mode: getBrowserWorkspaceMode(env),
|
|
817
|
+
subaction: command.subaction,
|
|
818
|
+
closed: await closeBrowserWorkspaceTab(targetId, env)
|
|
819
|
+
};
|
|
820
|
+
}
|
|
821
|
+
case "window":
|
|
822
|
+
return {
|
|
823
|
+
mode: getBrowserWorkspaceMode(env),
|
|
824
|
+
subaction: command.subaction,
|
|
825
|
+
tab: await openBrowserWorkspaceTab(
|
|
826
|
+
{
|
|
827
|
+
partition: resolveBrowserWorkspaceCommandPartition(
|
|
828
|
+
command,
|
|
829
|
+
AGENT_BROWSER_WORKSPACE_PARTITION
|
|
830
|
+
),
|
|
831
|
+
show: true,
|
|
832
|
+
title: command.title,
|
|
833
|
+
url: command.url,
|
|
834
|
+
width: command.width,
|
|
835
|
+
height: command.height
|
|
836
|
+
},
|
|
837
|
+
env
|
|
838
|
+
)
|
|
839
|
+
};
|
|
840
|
+
case "back":
|
|
841
|
+
case "forward":
|
|
842
|
+
case "reload": {
|
|
843
|
+
if (isBrowserWorkspaceBridgeConfigured(env)) {
|
|
844
|
+
const id = await resolveDesktopBrowserWorkspaceTargetTabId(
|
|
845
|
+
command,
|
|
846
|
+
env
|
|
847
|
+
);
|
|
848
|
+
clearBrowserWorkspaceElementRefs("desktop", id);
|
|
849
|
+
return executeDesktopBrowserWorkspaceDomCommand(command, env);
|
|
850
|
+
}
|
|
851
|
+
return withWebStateLock(async () => {
|
|
852
|
+
const id = findWebBrowserWorkspaceTargetTabId(command);
|
|
853
|
+
const tab = getWebBrowserWorkspaceTabState(id);
|
|
854
|
+
if (command.subaction === "reload") {
|
|
855
|
+
clearWebBrowserWorkspaceTabElementRefs(tab.id);
|
|
856
|
+
tab.dom = null;
|
|
857
|
+
tab.loadedUrl = null;
|
|
858
|
+
await loadWebBrowserWorkspaceTabDocument(tab);
|
|
859
|
+
return {
|
|
860
|
+
mode: "web",
|
|
861
|
+
subaction: command.subaction,
|
|
862
|
+
tab: cloneWebBrowserWorkspaceTabState(tab),
|
|
863
|
+
value: { url: tab.url, title: tab.title }
|
|
864
|
+
};
|
|
865
|
+
}
|
|
866
|
+
const delta = command.subaction === "back" ? -1 : 1;
|
|
867
|
+
const nextIndex = tab.historyIndex + delta;
|
|
868
|
+
if (nextIndex < 0 || nextIndex >= tab.history.length) {
|
|
869
|
+
return {
|
|
870
|
+
mode: "web",
|
|
871
|
+
subaction: command.subaction,
|
|
872
|
+
tab: cloneWebBrowserWorkspaceTabState(tab),
|
|
873
|
+
value: { url: tab.url, title: tab.title, changed: false }
|
|
874
|
+
};
|
|
875
|
+
}
|
|
876
|
+
tab.historyIndex = nextIndex;
|
|
877
|
+
tab.url = tab.history[nextIndex] ?? tab.url;
|
|
878
|
+
tab.title = inferBrowserWorkspaceTitle(tab.url);
|
|
879
|
+
clearWebBrowserWorkspaceTabElementRefs(tab.id);
|
|
880
|
+
tab.dom = null;
|
|
881
|
+
tab.loadedUrl = null;
|
|
882
|
+
await loadWebBrowserWorkspaceTabDocument(tab);
|
|
883
|
+
return {
|
|
884
|
+
mode: "web",
|
|
885
|
+
subaction: command.subaction,
|
|
886
|
+
tab: cloneWebBrowserWorkspaceTabState(tab),
|
|
887
|
+
value: { url: tab.url, title: tab.title, changed: true }
|
|
888
|
+
};
|
|
889
|
+
});
|
|
890
|
+
}
|
|
891
|
+
case "inspect":
|
|
892
|
+
case "snapshot":
|
|
893
|
+
case "check":
|
|
894
|
+
case "click":
|
|
895
|
+
case "dblclick":
|
|
896
|
+
case "find":
|
|
897
|
+
case "fill":
|
|
898
|
+
case "focus":
|
|
899
|
+
case "get":
|
|
900
|
+
case "hover":
|
|
901
|
+
case "keydown":
|
|
902
|
+
case "keyup":
|
|
903
|
+
case "keyboardinserttext":
|
|
904
|
+
case "keyboardtype":
|
|
905
|
+
case "press":
|
|
906
|
+
case "scroll":
|
|
907
|
+
case "scrollinto":
|
|
908
|
+
case "select":
|
|
909
|
+
case "type":
|
|
910
|
+
case "uncheck":
|
|
911
|
+
case "wait":
|
|
912
|
+
case "realistic-click":
|
|
913
|
+
case "realistic-fill":
|
|
914
|
+
case "realistic-type":
|
|
915
|
+
case "realistic-press":
|
|
916
|
+
case "realistic-upload":
|
|
917
|
+
case "cursor-move":
|
|
918
|
+
case "cursor-hide":
|
|
919
|
+
if (command.subaction === "wait" && !command.selector && !command.findBy && !command.text && !command.url && !command.script && typeof command.timeoutMs === "number" && Number.isFinite(command.timeoutMs)) {
|
|
920
|
+
const waitedMs = Math.max(0, command.timeoutMs);
|
|
921
|
+
await sleep(waitedMs);
|
|
922
|
+
return {
|
|
923
|
+
mode: getBrowserWorkspaceMode(env),
|
|
924
|
+
subaction: command.subaction,
|
|
925
|
+
value: { waitedMs }
|
|
926
|
+
};
|
|
927
|
+
}
|
|
928
|
+
if (isBrowserWorkspaceBridgeConfigured(env)) {
|
|
929
|
+
return executeDesktopBrowserWorkspaceDomCommand(command, env);
|
|
930
|
+
}
|
|
931
|
+
return executeWebBrowserWorkspaceDomCommand(command);
|
|
932
|
+
default: {
|
|
933
|
+
const exhaustive = command.subaction;
|
|
934
|
+
throw new Error(`Unsupported browser workspace subaction: ${exhaustive}`);
|
|
935
|
+
}
|
|
936
|
+
}
|
|
937
|
+
}
|
|
938
|
+
export {
|
|
939
|
+
BROWSER_WORKSPACE_CONNECTOR_AUTH_STATES,
|
|
940
|
+
__resetBrowserWorkspaceStateForTests,
|
|
941
|
+
acquireBrowserWorkspaceConnectorSession,
|
|
942
|
+
closeBrowserWorkspaceTab,
|
|
943
|
+
evaluateBrowserWorkspaceTab,
|
|
944
|
+
executeBrowserWorkspaceCommand,
|
|
945
|
+
getBrowserWorkspaceMode,
|
|
946
|
+
getBrowserWorkspaceSnapshot,
|
|
947
|
+
getBrowserWorkspaceUnavailableMessage,
|
|
948
|
+
hideBrowserWorkspaceTab,
|
|
949
|
+
isBrowserWorkspaceBridgeConfigured,
|
|
950
|
+
listBrowserWorkspaceTabs,
|
|
951
|
+
navigateBrowserWorkspaceTab,
|
|
952
|
+
openBrowserWorkspaceTab,
|
|
953
|
+
resolveBrowserWorkspaceBridgeConfig,
|
|
954
|
+
resolveBrowserWorkspaceConnectorPartition,
|
|
955
|
+
showBrowserWorkspaceTab,
|
|
956
|
+
snapshotBrowserWorkspaceTab
|
|
957
|
+
};
|
|
958
|
+
//# sourceMappingURL=browser-workspace.js.map
|