@memberjunction/remote-browser-base 0.0.1 → 5.41.0
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 +145 -40
- package/dist/base-remote-browser-provider.d.ts +149 -0
- package/dist/base-remote-browser-provider.d.ts.map +1 -0
- package/dist/base-remote-browser-provider.js +95 -0
- package/dist/base-remote-browser-provider.js.map +1 -0
- package/dist/capability-errors.d.ts +47 -0
- package/dist/capability-errors.d.ts.map +1 -0
- package/dist/capability-errors.js +44 -0
- package/dist/capability-errors.js.map +1 -0
- package/dist/control.d.ts +69 -0
- package/dist/control.d.ts.map +1 -0
- package/dist/control.js +52 -0
- package/dist/control.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/remote-browser-engine-base.d.ts +76 -0
- package/dist/remote-browser-engine-base.d.ts.map +1 -0
- package/dist/remote-browser-engine-base.js +116 -0
- package/dist/remote-browser-engine-base.js.map +1 -0
- package/dist/remote-browser-features.d.ts +46 -0
- package/dist/remote-browser-features.d.ts.map +1 -0
- package/dist/remote-browser-features.js +37 -0
- package/dist/remote-browser-features.js.map +1 -0
- package/dist/remote-browser-session.d.ts +376 -0
- package/dist/remote-browser-session.d.ts.map +1 -0
- package/dist/remote-browser-session.js +15 -0
- package/dist/remote-browser-session.js.map +1 -0
- package/package.json +32 -7
package/README.md
CHANGED
|
@@ -1,45 +1,150 @@
|
|
|
1
1
|
# @memberjunction/remote-browser-base
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Universal (client **and** server), **metadata-only** base layer for the MemberJunction **Remote
|
|
4
|
+
Browser channel** — the in-house channel where an agent **spins up a real Chromium browser, drives it
|
|
5
|
+
over CDP while it talks, screen-shares it live, and can hand the wheel to a human** (a sales agent
|
|
6
|
+
running an interactive product demo, a support agent walking a user through a UI, a trainer agent that
|
|
7
|
+
demonstrates a task then watches you try).
|
|
8
|
+
|
|
9
|
+
This package holds everything the Remote Browser channel needs that carries **no execution** — the
|
|
10
|
+
backend-provider registry cache, the abstract `BaseRemoteBrowserProvider` driver contract, the live
|
|
11
|
+
CDP-backed `IRemoteBrowserSession` interface plus its self-contained action / input / frame types, the
|
|
12
|
+
control-mode/strategy helpers, and the capability-error type. It is the base half of the
|
|
13
|
+
`RemoteBrowserEngineBase` / `RemoteBrowserEngine` pair, exactly mirroring how
|
|
14
|
+
[`@memberjunction/ai-bridge-base`](../../RealtimeBridge/Base)'s `BaseRealtimeBridge` /
|
|
15
|
+
`AIBridgeEngineBase` underpin the bridge server tier. The server tier that actually *runs* a
|
|
16
|
+
remote-browser session (CDP-connect via `@memberjunction/computer-use`, the live sessions, control
|
|
17
|
+
arbitration, the viewport→screen-track encode) lives in the Server package; the five backend drivers
|
|
18
|
+
(Self-Hosted Chrome, Browserbase, Steel, Browserless, Hyperbrowser) live alongside it.
|
|
19
|
+
|
|
20
|
+
> See the architecture plan at `/plans/realtime/realtime-bridges-architecture.md` §4d (the Remote
|
|
21
|
+
> Browser channel) and §4d-i (the option-3 build decision: one CDP primitive, pluggable backends, the
|
|
22
|
+
> MJ way) for the full design.
|
|
23
|
+
|
|
24
|
+
## What's in the box
|
|
25
|
+
|
|
26
|
+
| Export | Purpose |
|
|
27
|
+
|---|---|
|
|
28
|
+
| `BaseRemoteBrowserProvider` | The abstract driver. A concrete backend (`BrowserbaseRemoteBrowser`, `SelfHostedChromeRemoteBrowser`, …) implements only the irreducibly backend-specific primitives (`Connect` → returns a live `IRemoteBrowserSession`, `Disconnect`). Drivers self-register via `@RegisterClass(BaseRemoteBrowserProvider, '<X>RemoteBrowser')`. |
|
|
29
|
+
| `RemoteBrowserEngineBase` | A `BaseEngine` singleton caching the backend registry (`MJ: AI Remote Browser Providers` + capability flags) with synchronous resolution helpers (`ProviderByName`, `ProviderByDriverClass`, `ActiveProviders`, `FeaturesFor`). No execution. |
|
|
30
|
+
| `IRemoteBrowserSession` | The live-session contract — core CDP methods (`GetCdpEndpoint`, `Navigate`, `ExecuteAction`, `CaptureScreenshot`, `GetCurrentUrl`, `Close`) plus capability-gated ones (`GetLiveViewUrl`, `StartScreencast`/`StopScreencast`, `RouteHumanInput`, `InvokeNativeAIControl`). |
|
|
31
|
+
| Action / input / frame types | `RemoteBrowserAction` (discriminated union: navigate / click / type / key / scroll / back / forward / wait), `RemoteBrowserActionResult`, `RemoteBrowserScreencastFrame`, `RemoteBrowserHumanInput` (pointer-move / pointer-click / key) — all strongly typed, **self-contained** (no Playwright / computer-use dependency). |
|
|
32
|
+
| `RemoteBrowserControlMode` + `RemoteBrowserControlStrategy` + helpers | `isControlModeSupported(mode, features)`, `resolveControlStrategy(features, preferred?)` — pure, capability-aware helpers. |
|
|
33
|
+
| `RemoteBrowserCapabilityNotSupportedError` | The defense-in-depth error thrown when a capability-gated method is called on a backend that doesn't support it (carries `FeatureName` + `ProviderName`). |
|
|
34
|
+
| `IRemoteBrowserProviderFeatures` + `featuresOf` + `KNOWN_REMOTE_BROWSER_FEATURE_KEYS` | Typed alias of the generated `MJ: AI Remote Browser Providers.SupportedFeatures` shape, a null-safe reader, and the full key list for validators/iteration. |
|
|
35
|
+
|
|
36
|
+
## Installation
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
npm install @memberjunction/remote-browser-base
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## The universal CDP substrate
|
|
43
|
+
|
|
44
|
+
Every backend — self-hosted headless Chrome **and** every browser-as-a-service (Browserbase, Steel,
|
|
45
|
+
Browserless, Hyperbrowser) — exposes a **Chrome DevTools Protocol** endpoint. The Remote Browser
|
|
46
|
+
subsystem standardizes on **CDP-connect** as its one primitive: the server engine connects over CDP
|
|
47
|
+
(reusing `@memberjunction/computer-use`'s `PlaywrightBrowserAdapter`) and drives a clean
|
|
48
|
+
click/type/scroll/screenshot vocabulary — no hand-rolled raw CDP. This Base package itself stays
|
|
49
|
+
dependency-light and universal precisely because it only *declares* the `IRemoteBrowserSession`
|
|
50
|
+
contract both sides agree on; the Playwright/CDP machinery lives in the server tier.
|
|
51
|
+
|
|
52
|
+
## The driver contract
|
|
53
|
+
|
|
54
|
+
`BaseRemoteBrowserProvider` is intentionally tiny — two abstract methods:
|
|
55
|
+
|
|
56
|
+
- **`Connect(ctx)`** — open or attach a browser over CDP and return the live `IRemoteBrowserSession`.
|
|
57
|
+
Call `this.applyContext(ctx)` first to capture the backend's capability flags + name.
|
|
58
|
+
- **`Disconnect()`** — release the driver's own backend resources (tear down the container, end the
|
|
59
|
+
service session).
|
|
60
|
+
|
|
61
|
+
Protected helpers for driver authors: `applyContext(ctx)` (capture features + provider name — call it
|
|
62
|
+
first in `Connect`), `RequireFeature(flag)` (re-assert a capability flag before gated work), and
|
|
63
|
+
`notSupported(name)` (build the standard error).
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
import { RegisterClass } from '@memberjunction/global';
|
|
67
|
+
import {
|
|
68
|
+
BaseRemoteBrowserProvider,
|
|
69
|
+
IRemoteBrowserSession,
|
|
70
|
+
RemoteBrowserProviderContext,
|
|
71
|
+
} from '@memberjunction/remote-browser-base';
|
|
72
|
+
|
|
73
|
+
@RegisterClass(BaseRemoteBrowserProvider, 'BrowserbaseRemoteBrowser')
|
|
74
|
+
export class BrowserbaseRemoteBrowser extends BaseRemoteBrowserProvider {
|
|
75
|
+
public async Connect(ctx: RemoteBrowserProviderContext): Promise<IRemoteBrowserSession> {
|
|
76
|
+
this.applyContext(ctx); // capture features + provider name (do this first)
|
|
77
|
+
// ...request a session from the backend, obtain its CDP endpoint, and return a session that
|
|
78
|
+
// implements IRemoteBrowserSession (the actual CDP wiring lives in the server tier).
|
|
79
|
+
throw new Error('implemented in the server / driver package');
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
public async Disconnect(): Promise<void> {
|
|
83
|
+
// ...release the backend session.
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
A provider row whose `DriverClass = 'BrowserbaseRemoteBrowser'` resolves to this driver through the
|
|
89
|
+
`ClassFactory`: `MJGlobal.ClassFactory.CreateInstance(BaseRemoteBrowserProvider, provider.DriverClass)`.
|
|
90
|
+
|
|
91
|
+
## Capability gating (two layers, defense-in-depth)
|
|
92
|
+
|
|
93
|
+
A backend's capabilities live in the `MJ: AI Remote Browser Providers.SupportedFeatures` JSON column,
|
|
94
|
+
strongly typed via `IRemoteBrowserProviderFeatures`. It holds **control/transport** concerns only:
|
|
95
|
+
|
|
96
|
+
- **Control substrate & strategies** — `RawCdpControl` (the universal substrate), `NativeAIControl` (a
|
|
97
|
+
backend's own AI-control harness, e.g. Stagehand).
|
|
98
|
+
- **Viewing & collaboration** — `LiveView`, `HumanTakeover`, `ScreenStreaming`.
|
|
99
|
+
- **Operational** — `Stealth`, `ProxyEgress`, `SessionRecording`, `PersistentContext`, `MultiTab`,
|
|
100
|
+
`FileDownloads`, `CaptchaSolving`.
|
|
101
|
+
|
|
102
|
+
The engine checks the matching flag **first** and never calls a capability-gated session method whose
|
|
103
|
+
feature is off; the capability-gated method's own throw is the **second**, defense-in-depth layer for
|
|
104
|
+
when a metadata flag lies or a caller bypasses the gate. New backend features need no schema migration
|
|
105
|
+
— extend the interface. Read flags via `provider.SupportedFeaturesObject` (or the null-safe
|
|
106
|
+
`featuresOf(provider)`), never `JSON.parse(provider.SupportedFeatures)`.
|
|
107
|
+
|
|
108
|
+
## Control modes vs. control strategies
|
|
109
|
+
|
|
110
|
+
These are **orthogonal** axes — keep them straight:
|
|
111
|
+
|
|
112
|
+
| Axis | Type | Meaning |
|
|
113
|
+
|---|---|---|
|
|
114
|
+
| **Control mode** | `RemoteBrowserControlMode` | *Who* drives: `AgentOnly` (no takeover) · `ViewOnly` (humans watch — needs `LiveView`) · `Collaborative` (a human can grab the wheel — needs `LiveView` + `HumanTakeover`). A per-provider `DefaultControlMode`, overridable per-channel and at runtime. |
|
|
115
|
+
| **Control strategy** | `RemoteBrowserControlStrategy` | *How* the agent decides what to do: `ComputerUse` (MJ's perception→action loop over CDP — the universal default) · `NativeAI` (delegate intents to the backend's own harness — needs `NativeAIControl`). |
|
|
116
|
+
|
|
117
|
+
```typescript
|
|
118
|
+
import {
|
|
119
|
+
isControlModeSupported,
|
|
120
|
+
resolveControlStrategy,
|
|
121
|
+
} from '@memberjunction/remote-browser-base';
|
|
122
|
+
|
|
123
|
+
const features = provider.SupportedFeaturesObject ?? {};
|
|
124
|
+
|
|
125
|
+
isControlModeSupported('Collaborative', features); // true only if LiveView && HumanTakeover
|
|
126
|
+
resolveControlStrategy(features); // 'NativeAI' iff features.NativeAIControl, else 'ComputerUse'
|
|
127
|
+
resolveControlStrategy(features, 'ComputerUse'); // always 'ComputerUse' — explicit ComputerUse pins the universal loop
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## How it composes
|
|
131
|
+
|
|
132
|
+
| Layer | Package | Role |
|
|
133
|
+
|---|---|---|
|
|
134
|
+
| **Registry cache + abstract driver + session contract + control helpers** | **`@memberjunction/remote-browser-base`** (this) | provider cache, `BaseRemoteBrowserProvider`, `IRemoteBrowserSession`, action/input types, control mode/strategy, capability types |
|
|
135
|
+
| Coordination + execution (CDP-connect, control arbiter, screen-track encode) | server package | `RemoteBrowserEngine` (composes this base), live sessions, the `RemoteBrowserChannel` |
|
|
136
|
+
| Browser control vocabulary | [`@memberjunction/computer-use`](../../ComputerUse) | the `PlaywrightBrowserAdapter` the server tier uses to drive CDP — **not** a dependency of this base |
|
|
4
137
|
|
|
5
|
-
|
|
138
|
+
The server `RemoteBrowserEngine` **composes** (does not extend) `RemoteBrowserEngineBase`, so the
|
|
139
|
+
startup manager warms exactly one `BaseEngine` cache — the same composition-over-inheritance pattern
|
|
140
|
+
`AIBridgeEngine` uses over `AIBridgeEngineBase`.
|
|
6
141
|
|
|
7
|
-
|
|
142
|
+
## Further reading
|
|
143
|
+
|
|
144
|
+
- **Architecture plan:** `/plans/realtime/realtime-bridges-architecture.md` §4d / §4d-i.
|
|
145
|
+
- **Sibling subsystem:** [`@memberjunction/ai-bridge-base`](../../RealtimeBridge/Base/README.md) — the
|
|
146
|
+
realtime media bridge this package mirrors in structure and style.
|
|
147
|
+
|
|
148
|
+
## License
|
|
8
149
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
This package exists to:
|
|
12
|
-
1. Configure OIDC trusted publishing for the package name `@memberjunction/remote-browser-base`
|
|
13
|
-
2. Enable secure, token-less publishing from CI/CD workflows
|
|
14
|
-
3. Establish provenance for packages published under this name
|
|
15
|
-
|
|
16
|
-
## What is OIDC Trusted Publishing?
|
|
17
|
-
|
|
18
|
-
OIDC trusted publishing allows package maintainers to publish packages directly from their CI/CD workflows without needing to manage npm access tokens. Instead, it uses OpenID Connect to establish trust between the CI/CD provider (like GitHub Actions) and npm.
|
|
19
|
-
|
|
20
|
-
## Setup Instructions
|
|
21
|
-
|
|
22
|
-
To properly configure OIDC trusted publishing for this package:
|
|
23
|
-
|
|
24
|
-
1. Go to [npmjs.com](https://www.npmjs.com/) and navigate to your package settings
|
|
25
|
-
2. Configure the trusted publisher (e.g., GitHub Actions)
|
|
26
|
-
3. Specify the repository and workflow that should be allowed to publish
|
|
27
|
-
4. Use the configured workflow to publish your actual package
|
|
28
|
-
|
|
29
|
-
## DO NOT USE THIS PACKAGE
|
|
30
|
-
|
|
31
|
-
This package is a placeholder for OIDC configuration only. It:
|
|
32
|
-
- Contains no executable code
|
|
33
|
-
- Provides no functionality
|
|
34
|
-
- Should not be installed as a dependency
|
|
35
|
-
- Exists only for administrative purposes
|
|
36
|
-
|
|
37
|
-
## More Information
|
|
38
|
-
|
|
39
|
-
For more details about npm's trusted publishing feature, see:
|
|
40
|
-
- [npm Trusted Publishing Documentation](https://docs.npmjs.com/generating-provenance-statements)
|
|
41
|
-
- [GitHub Actions OIDC Documentation](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect)
|
|
42
|
-
|
|
43
|
-
---
|
|
44
|
-
|
|
45
|
-
**Maintained for OIDC setup purposes only**
|
|
150
|
+
ISC
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { UserInfo } from '@memberjunction/core';
|
|
2
|
+
import { IRemoteBrowserProviderFeatures } from './remote-browser-features.js';
|
|
3
|
+
import { RemoteBrowserControlMode } from './control.js';
|
|
4
|
+
import { IRemoteBrowserSession } from './remote-browser-session.js';
|
|
5
|
+
import { RemoteBrowserCapabilityNotSupportedError } from './capability-errors.js';
|
|
6
|
+
/**
|
|
7
|
+
* The set of host services a remote-browser driver sees while running.
|
|
8
|
+
*
|
|
9
|
+
* The engine (`RemoteBrowserEngine`, server package) constructs this and hands it to {@link
|
|
10
|
+
* BaseRemoteBrowserProvider.Connect}. It is deliberately small: a driver should depend only on what it
|
|
11
|
+
* truly needs, and everything richer (the realtime session, the channel plane, the control arbiter)
|
|
12
|
+
* is wired by the engine AROUND the driver, not handed into it. This keeps drivers thin and
|
|
13
|
+
* backend-focused.
|
|
14
|
+
*/
|
|
15
|
+
export interface RemoteBrowserProviderContext {
|
|
16
|
+
/**
|
|
17
|
+
* The backend's `SupportedFeatures` — the capability flags the engine and the driver's
|
|
18
|
+
* `RequireFeature` guard gate on. Sourced from the provider metadata row's typed
|
|
19
|
+
* `SupportedFeaturesObject` accessor (never `JSON.parse`).
|
|
20
|
+
*/
|
|
21
|
+
Features: IRemoteBrowserProviderFeatures;
|
|
22
|
+
/**
|
|
23
|
+
* The backend's display name (e.g. `'Browserbase'`, `'Self-Hosted Chrome'`), used in
|
|
24
|
+
* capability-error messages and logging.
|
|
25
|
+
*/
|
|
26
|
+
ProviderName: string;
|
|
27
|
+
/**
|
|
28
|
+
* How the browser is hosted: `'SelfHost'` (MJ orchestrates a lightweight headless-Chrome
|
|
29
|
+
* container we connect to over CDP) or `'Service'` (a browser-as-a-service exposes a CDP connect
|
|
30
|
+
* endpoint). Mirrors `MJ: AI Remote Browser Providers.ProviderType`.
|
|
31
|
+
*/
|
|
32
|
+
ProviderType: 'SelfHost' | 'Service';
|
|
33
|
+
/**
|
|
34
|
+
* The resolved control mode for this session (`AgentOnly` / `ViewOnly` / `Collaborative`) — the
|
|
35
|
+
* provider default overridden per-channel / at runtime. The driver uses it to decide whether to
|
|
36
|
+
* stand up live-view / takeover plumbing on connect.
|
|
37
|
+
*/
|
|
38
|
+
ControlMode: RemoteBrowserControlMode;
|
|
39
|
+
/**
|
|
40
|
+
* Opaque, backend-specific connection configuration (resolved credential references, region,
|
|
41
|
+
* Chrome image, proxy settings, …) as a parsed JSON object. Typed as a record of unknown values
|
|
42
|
+
* rather than `any` so it stays inspectable without losing type-safety at the boundary; the
|
|
43
|
+
* driver narrows the fields it understands. Never carries inline secrets — credentials resolve
|
|
44
|
+
* through MJ's credential system upstream and arrive here already resolved or as references.
|
|
45
|
+
*/
|
|
46
|
+
Configuration?: Record<string, unknown>;
|
|
47
|
+
/**
|
|
48
|
+
* The MJ user the remote-browser session runs as. Every session is owned by a user and fully
|
|
49
|
+
* audited; the driver uses this for any server-side operations that require a context user.
|
|
50
|
+
*/
|
|
51
|
+
ContextUser?: UserInfo;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Abstract base class for a **Remote Browser** provider driver — a pluggable backend that opens (or
|
|
55
|
+
* attaches to) a real Chromium browser over the Chrome DevTools Protocol and returns a live
|
|
56
|
+
* {@link IRemoteBrowserSession} the agent drives.
|
|
57
|
+
*
|
|
58
|
+
* This is the sibling of `BaseRealtimeBridge`: the Remote Browser channel is built exactly like the
|
|
59
|
+
* bridge subsystem (registry table + base driver + EngineBase/Engine pair + pluggable backends). A
|
|
60
|
+
* concrete driver (`SelfHostedChromeRemoteBrowser`, `BrowserbaseRemoteBrowser`, …) implements only the
|
|
61
|
+
* irreducibly backend-specific primitives — everything generic (control arbitration, the
|
|
62
|
+
* viewport→screen-track encode, session bookkeeping) lives in the server engine above. Drivers
|
|
63
|
+
* self-register with the MemberJunction `ClassFactory` — e.g.
|
|
64
|
+
* `@RegisterClass(BaseRemoteBrowserProvider, 'BrowserbaseRemoteBrowser')`. The base class itself is
|
|
65
|
+
* abstract and unregistered; the engine resolves a driver via
|
|
66
|
+
* `MJGlobal.ClassFactory.CreateInstance(BaseRemoteBrowserProvider, provider.DriverClass)`.
|
|
67
|
+
*
|
|
68
|
+
* **Capability gating (two layers, defense-in-depth).** The engine FIRST checks a provider's
|
|
69
|
+
* `SupportedFeatures` flag and never calls a session method whose feature is off. The driver's own
|
|
70
|
+
* capability-gated work is the SECOND layer: it calls {@link BaseRemoteBrowserProvider.RequireFeature}
|
|
71
|
+
* (or builds an error via {@link BaseRemoteBrowserProvider.notSupported}) so a metadata flag that
|
|
72
|
+
* lied — or a caller that bypassed the gate — fails loudly rather than silently degrading.
|
|
73
|
+
*
|
|
74
|
+
* **Universal CDP substrate.** Every backend (self-hosted Chrome and every browser-as-a-service)
|
|
75
|
+
* exposes a CDP endpoint; the engine standardizes on CDP-connect (reusing `@memberjunction/computer-use`
|
|
76
|
+
* server-side) so this Base package itself stays dependency-light and universal.
|
|
77
|
+
*
|
|
78
|
+
* @see `/plans/realtime/realtime-bridges-architecture.md` §4d / §4d-i.
|
|
79
|
+
* @abstract
|
|
80
|
+
*/
|
|
81
|
+
export declare abstract class BaseRemoteBrowserProvider {
|
|
82
|
+
/**
|
|
83
|
+
* The capability flags for the backend this driver instance serves. Populated from the
|
|
84
|
+
* {@link RemoteBrowserProviderContext} at {@link BaseRemoteBrowserProvider.Connect} time (call
|
|
85
|
+
* `this.applyContext(ctx)` first). Drives {@link BaseRemoteBrowserProvider.RequireFeature}.
|
|
86
|
+
*/
|
|
87
|
+
protected features: IRemoteBrowserProviderFeatures;
|
|
88
|
+
/**
|
|
89
|
+
* The backend's display name for this driver instance, used in capability-error messages.
|
|
90
|
+
* Populated from the {@link RemoteBrowserProviderContext}; falls back to the driver class name.
|
|
91
|
+
*/
|
|
92
|
+
protected providerName: string;
|
|
93
|
+
/**
|
|
94
|
+
* The backend's supported-feature flags for this driver instance.
|
|
95
|
+
*
|
|
96
|
+
* Read-only accessor over the internally-held {@link BaseRemoteBrowserProvider.features}. The
|
|
97
|
+
* engine consults this (and the underlying provider metadata) to decide which capability-gated
|
|
98
|
+
* session methods are safe to call; a driver consults it via
|
|
99
|
+
* {@link BaseRemoteBrowserProvider.RequireFeature}.
|
|
100
|
+
*/
|
|
101
|
+
get Features(): IRemoteBrowserProviderFeatures;
|
|
102
|
+
/**
|
|
103
|
+
* Opens or attaches a browser session on the backend over CDP and returns the live handle.
|
|
104
|
+
*
|
|
105
|
+
* Implementations must normalize the backend's capability flags + provider name into the
|
|
106
|
+
* instance (typically by calling `this.applyContext(ctx)` first), then establish the CDP-connected
|
|
107
|
+
* browser and return an {@link IRemoteBrowserSession} wrapping it.
|
|
108
|
+
*
|
|
109
|
+
* @param ctx The host services and connection parameters for this session.
|
|
110
|
+
* @returns A promise resolving to the live remote-browser session handle.
|
|
111
|
+
*/
|
|
112
|
+
abstract Connect(ctx: RemoteBrowserProviderContext): Promise<IRemoteBrowserSession>;
|
|
113
|
+
/**
|
|
114
|
+
* Tears down / releases the backend session this driver opened (closes the container, ends the
|
|
115
|
+
* browser-as-a-service session, …). Distinct from {@link IRemoteBrowserSession.Close}, which the
|
|
116
|
+
* engine may call on the session handle; `Disconnect` releases the driver's own backend resources.
|
|
117
|
+
*
|
|
118
|
+
* @returns A promise that resolves once the backend session has been released.
|
|
119
|
+
*/
|
|
120
|
+
abstract Disconnect(): Promise<void>;
|
|
121
|
+
/**
|
|
122
|
+
* Captures the connection context onto the instance so {@link BaseRemoteBrowserProvider.Features},
|
|
123
|
+
* {@link BaseRemoteBrowserProvider.RequireFeature}, and capability-error messages have the
|
|
124
|
+
* backend's flags and name. A concrete {@link BaseRemoteBrowserProvider.Connect} should call this
|
|
125
|
+
* first.
|
|
126
|
+
*
|
|
127
|
+
* @param ctx The provider context handed to `Connect`.
|
|
128
|
+
*/
|
|
129
|
+
protected applyContext(ctx: RemoteBrowserProviderContext): void;
|
|
130
|
+
/**
|
|
131
|
+
* Defense-in-depth guard: asserts a `SupportedFeatures` flag is enabled before the driver performs
|
|
132
|
+
* a capability-gated action, throwing {@link RemoteBrowserCapabilityNotSupportedError} if it is
|
|
133
|
+
* false/omitted. A driver should call this at the top of any capability-gated work so that even a
|
|
134
|
+
* direct (engine-bypassing) caller cannot run an action the metadata says is off.
|
|
135
|
+
*
|
|
136
|
+
* @param featureName The `IRemoteBrowserProviderFeatures` flag to require.
|
|
137
|
+
* @throws {RemoteBrowserCapabilityNotSupportedError} when the flag is not enabled.
|
|
138
|
+
*/
|
|
139
|
+
protected RequireFeature(featureName: keyof IRemoteBrowserProviderFeatures): void;
|
|
140
|
+
/**
|
|
141
|
+
* Builds the standard {@link RemoteBrowserCapabilityNotSupportedError} for an un-overridden
|
|
142
|
+
* capability or a failed feature requirement, stamped with this driver's backend name.
|
|
143
|
+
*
|
|
144
|
+
* @param featureName The feature / method name to report.
|
|
145
|
+
* @returns The error to throw or reject with.
|
|
146
|
+
*/
|
|
147
|
+
protected notSupported(featureName: string): RemoteBrowserCapabilityNotSupportedError;
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=base-remote-browser-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-remote-browser-provider.d.ts","sourceRoot":"","sources":["../src/base-remote-browser-provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,8BAA8B,EAAE,MAAM,2BAA2B,CAAC;AAC3E,OAAO,EAAE,wBAAwB,EAAE,MAAM,WAAW,CAAC;AACrD,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EAAE,wCAAwC,EAAE,MAAM,qBAAqB,CAAC;AAE/E;;;;;;;;GAQG;AACH,MAAM,WAAW,4BAA4B;IACzC;;;;OAIG;IACH,QAAQ,EAAE,8BAA8B,CAAC;IAEzC;;;OAGG;IACH,YAAY,EAAE,MAAM,CAAC;IAErB;;;;OAIG;IACH,YAAY,EAAE,UAAU,GAAG,SAAS,CAAC;IAErC;;;;OAIG;IACH,WAAW,EAAE,wBAAwB,CAAC;IAEtC;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAExC;;;OAGG;IACH,WAAW,CAAC,EAAE,QAAQ,CAAC;CAC1B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,8BAAsB,yBAAyB;IAC3C;;;;OAIG;IACH,SAAS,CAAC,QAAQ,EAAE,8BAA8B,CAAM;IAExD;;;OAGG;IACH,SAAS,CAAC,YAAY,EAAE,MAAM,CAAM;IAEpC;;;;;;;OAOG;IACH,IAAW,QAAQ,IAAI,8BAA8B,CAEpD;IAMD;;;;;;;;;OASG;aACa,OAAO,CAAC,GAAG,EAAE,4BAA4B,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAE1F;;;;;;OAMG;aACa,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAM3C;;;;;;;OAOG;IACH,SAAS,CAAC,YAAY,CAAC,GAAG,EAAE,4BAA4B,GAAG,IAAI;IAK/D;;;;;;;;OAQG;IACH,SAAS,CAAC,cAAc,CAAC,WAAW,EAAE,MAAM,8BAA8B,GAAG,IAAI;IASjF;;;;;;OAMG;IACH,SAAS,CAAC,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,wCAAwC;CAMxF"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { RemoteBrowserCapabilityNotSupportedError } from './capability-errors.js';
|
|
2
|
+
/**
|
|
3
|
+
* Abstract base class for a **Remote Browser** provider driver — a pluggable backend that opens (or
|
|
4
|
+
* attaches to) a real Chromium browser over the Chrome DevTools Protocol and returns a live
|
|
5
|
+
* {@link IRemoteBrowserSession} the agent drives.
|
|
6
|
+
*
|
|
7
|
+
* This is the sibling of `BaseRealtimeBridge`: the Remote Browser channel is built exactly like the
|
|
8
|
+
* bridge subsystem (registry table + base driver + EngineBase/Engine pair + pluggable backends). A
|
|
9
|
+
* concrete driver (`SelfHostedChromeRemoteBrowser`, `BrowserbaseRemoteBrowser`, …) implements only the
|
|
10
|
+
* irreducibly backend-specific primitives — everything generic (control arbitration, the
|
|
11
|
+
* viewport→screen-track encode, session bookkeeping) lives in the server engine above. Drivers
|
|
12
|
+
* self-register with the MemberJunction `ClassFactory` — e.g.
|
|
13
|
+
* `@RegisterClass(BaseRemoteBrowserProvider, 'BrowserbaseRemoteBrowser')`. The base class itself is
|
|
14
|
+
* abstract and unregistered; the engine resolves a driver via
|
|
15
|
+
* `MJGlobal.ClassFactory.CreateInstance(BaseRemoteBrowserProvider, provider.DriverClass)`.
|
|
16
|
+
*
|
|
17
|
+
* **Capability gating (two layers, defense-in-depth).** The engine FIRST checks a provider's
|
|
18
|
+
* `SupportedFeatures` flag and never calls a session method whose feature is off. The driver's own
|
|
19
|
+
* capability-gated work is the SECOND layer: it calls {@link BaseRemoteBrowserProvider.RequireFeature}
|
|
20
|
+
* (or builds an error via {@link BaseRemoteBrowserProvider.notSupported}) so a metadata flag that
|
|
21
|
+
* lied — or a caller that bypassed the gate — fails loudly rather than silently degrading.
|
|
22
|
+
*
|
|
23
|
+
* **Universal CDP substrate.** Every backend (self-hosted Chrome and every browser-as-a-service)
|
|
24
|
+
* exposes a CDP endpoint; the engine standardizes on CDP-connect (reusing `@memberjunction/computer-use`
|
|
25
|
+
* server-side) so this Base package itself stays dependency-light and universal.
|
|
26
|
+
*
|
|
27
|
+
* @see `/plans/realtime/realtime-bridges-architecture.md` §4d / §4d-i.
|
|
28
|
+
* @abstract
|
|
29
|
+
*/
|
|
30
|
+
export class BaseRemoteBrowserProvider {
|
|
31
|
+
constructor() {
|
|
32
|
+
/**
|
|
33
|
+
* The capability flags for the backend this driver instance serves. Populated from the
|
|
34
|
+
* {@link RemoteBrowserProviderContext} at {@link BaseRemoteBrowserProvider.Connect} time (call
|
|
35
|
+
* `this.applyContext(ctx)` first). Drives {@link BaseRemoteBrowserProvider.RequireFeature}.
|
|
36
|
+
*/
|
|
37
|
+
this.features = {};
|
|
38
|
+
/**
|
|
39
|
+
* The backend's display name for this driver instance, used in capability-error messages.
|
|
40
|
+
* Populated from the {@link RemoteBrowserProviderContext}; falls back to the driver class name.
|
|
41
|
+
*/
|
|
42
|
+
this.providerName = '';
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* The backend's supported-feature flags for this driver instance.
|
|
46
|
+
*
|
|
47
|
+
* Read-only accessor over the internally-held {@link BaseRemoteBrowserProvider.features}. The
|
|
48
|
+
* engine consults this (and the underlying provider metadata) to decide which capability-gated
|
|
49
|
+
* session methods are safe to call; a driver consults it via
|
|
50
|
+
* {@link BaseRemoteBrowserProvider.RequireFeature}.
|
|
51
|
+
*/
|
|
52
|
+
get Features() {
|
|
53
|
+
return this.features;
|
|
54
|
+
}
|
|
55
|
+
// ──────────────────────────────────────────────────────────────────────────────
|
|
56
|
+
// Protected helpers for driver authors.
|
|
57
|
+
// ──────────────────────────────────────────────────────────────────────────────
|
|
58
|
+
/**
|
|
59
|
+
* Captures the connection context onto the instance so {@link BaseRemoteBrowserProvider.Features},
|
|
60
|
+
* {@link BaseRemoteBrowserProvider.RequireFeature}, and capability-error messages have the
|
|
61
|
+
* backend's flags and name. A concrete {@link BaseRemoteBrowserProvider.Connect} should call this
|
|
62
|
+
* first.
|
|
63
|
+
*
|
|
64
|
+
* @param ctx The provider context handed to `Connect`.
|
|
65
|
+
*/
|
|
66
|
+
applyContext(ctx) {
|
|
67
|
+
this.features = ctx.Features ?? {};
|
|
68
|
+
this.providerName = ctx.ProviderName || this.constructor.name;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Defense-in-depth guard: asserts a `SupportedFeatures` flag is enabled before the driver performs
|
|
72
|
+
* a capability-gated action, throwing {@link RemoteBrowserCapabilityNotSupportedError} if it is
|
|
73
|
+
* false/omitted. A driver should call this at the top of any capability-gated work so that even a
|
|
74
|
+
* direct (engine-bypassing) caller cannot run an action the metadata says is off.
|
|
75
|
+
*
|
|
76
|
+
* @param featureName The `IRemoteBrowserProviderFeatures` flag to require.
|
|
77
|
+
* @throws {RemoteBrowserCapabilityNotSupportedError} when the flag is not enabled.
|
|
78
|
+
*/
|
|
79
|
+
RequireFeature(featureName) {
|
|
80
|
+
if (this.features[featureName] !== true) {
|
|
81
|
+
throw new RemoteBrowserCapabilityNotSupportedError(String(featureName), this.providerName || this.constructor.name);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Builds the standard {@link RemoteBrowserCapabilityNotSupportedError} for an un-overridden
|
|
86
|
+
* capability or a failed feature requirement, stamped with this driver's backend name.
|
|
87
|
+
*
|
|
88
|
+
* @param featureName The feature / method name to report.
|
|
89
|
+
* @returns The error to throw or reject with.
|
|
90
|
+
*/
|
|
91
|
+
notSupported(featureName) {
|
|
92
|
+
return new RemoteBrowserCapabilityNotSupportedError(featureName, this.providerName || this.constructor.name);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=base-remote-browser-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-remote-browser-provider.js","sourceRoot":"","sources":["../src/base-remote-browser-provider.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,wCAAwC,EAAE,MAAM,qBAAqB,CAAC;AAuD/E;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,OAAgB,yBAAyB;IAA/C;QACI;;;;WAIG;QACO,aAAQ,GAAmC,EAAE,CAAC;QAExD;;;WAGG;QACO,iBAAY,GAAW,EAAE,CAAC;IAuFxC,CAAC;IArFG;;;;;;;OAOG;IACH,IAAW,QAAQ;QACf,OAAO,IAAI,CAAC,QAAQ,CAAC;IACzB,CAAC;IA2BD,iFAAiF;IACjF,wCAAwC;IACxC,iFAAiF;IAEjF;;;;;;;OAOG;IACO,YAAY,CAAC,GAAiC;QACpD,IAAI,CAAC,QAAQ,GAAG,GAAG,CAAC,QAAQ,IAAI,EAAE,CAAC;QACnC,IAAI,CAAC,YAAY,GAAG,GAAG,CAAC,YAAY,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;IAClE,CAAC;IAED;;;;;;;;OAQG;IACO,cAAc,CAAC,WAAiD;QACtE,IAAI,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,KAAK,IAAI,EAAE,CAAC;YACtC,MAAM,IAAI,wCAAwC,CAC9C,MAAM,CAAC,WAAW,CAAC,EACnB,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,CAC7C,CAAC;QACN,CAAC;IACL,CAAC;IAED;;;;;;OAMG;IACO,YAAY,CAAC,WAAmB;QACtC,OAAO,IAAI,wCAAwC,CAC/C,WAAW,EACX,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,CAC7C,CAAC;IACN,CAAC;CACJ"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error types for the remote-browser capability-gating flow.
|
|
3
|
+
*
|
|
4
|
+
* See `/plans/realtime/realtime-bridges-architecture.md` §4d-i — the Remote Browser channel is built
|
|
5
|
+
* exactly like the bridge subsystem (registry table + base driver + EngineBase/Engine pair +
|
|
6
|
+
* pluggable backends), with the same two-layer capability gating. The engine checks a provider's
|
|
7
|
+
* `SupportedFeatures` flag BEFORE calling an optional driver method; this error is the
|
|
8
|
+
* **defense-in-depth** layer that fires when a feature is claimed in metadata but the concrete driver
|
|
9
|
+
* never implemented it (or a caller skipped the metadata gate). Metadata says "don't call this"; the
|
|
10
|
+
* throw means the code refuses to pretend a capability exists.
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Thrown when a capability-gated remote-browser feature is invoked on a driver that does not support it.
|
|
14
|
+
*
|
|
15
|
+
* Two distinct failure modes both surface as this error:
|
|
16
|
+
* 1. A `BaseRemoteBrowserProvider` **virtual** method (e.g. `GetLiveViewUrl`, `StartScreencast`) was
|
|
17
|
+
* called but the concrete driver did not override the base implementation — the base throws this.
|
|
18
|
+
* 2. The driver's `RequireFeature(...)` defense-in-depth guard found the matching
|
|
19
|
+
* `IRemoteBrowserProviderFeatures` flag false/omitted — the metadata claims the feature is off, so
|
|
20
|
+
* the call must not proceed.
|
|
21
|
+
*
|
|
22
|
+
* Carrying both the `FeatureName` and the `ProviderName` makes the loud failure actionable: it points
|
|
23
|
+
* at exactly which capability flag lied (or which driver method is missing) for which backend.
|
|
24
|
+
*/
|
|
25
|
+
export declare class RemoteBrowserCapabilityNotSupportedError extends Error {
|
|
26
|
+
/**
|
|
27
|
+
* The name of the unsupported feature — by convention an `IRemoteBrowserProviderFeatures` key
|
|
28
|
+
* (e.g. `'LiveView'`, `'HumanTakeover'`, `'NativeAIControl'`) or the virtual method name when the
|
|
29
|
+
* throw originates from an un-overridden base method.
|
|
30
|
+
*/
|
|
31
|
+
readonly FeatureName: string;
|
|
32
|
+
/**
|
|
33
|
+
* The remote-browser backend the call targeted (e.g. `'Browserbase'`, `'Self-Hosted Chrome'`).
|
|
34
|
+
* Sourced from the provider metadata row's `Name`, or the driver's own identifier when the
|
|
35
|
+
* provider name is not available at the throw site.
|
|
36
|
+
*/
|
|
37
|
+
readonly ProviderName: string;
|
|
38
|
+
/**
|
|
39
|
+
* Constructs a {@link RemoteBrowserCapabilityNotSupportedError}.
|
|
40
|
+
*
|
|
41
|
+
* @param featureName The unsupported feature / method name (an `IRemoteBrowserProviderFeatures` key by convention).
|
|
42
|
+
* @param providerName The backend the call targeted (e.g. `'Browserbase'`, `'Steel'`).
|
|
43
|
+
* @param message Optional override for the human-readable message; a sensible default is built from the two names.
|
|
44
|
+
*/
|
|
45
|
+
constructor(featureName: string, providerName: string, message?: string);
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=capability-errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capability-errors.d.ts","sourceRoot":"","sources":["../src/capability-errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH;;;;;;;;;;;;GAYG;AACH,qBAAa,wCAAyC,SAAQ,KAAK;IAC/D;;;;OAIG;IACH,SAAgB,WAAW,EAAE,MAAM,CAAC;IAEpC;;;;OAIG;IACH,SAAgB,YAAY,EAAE,MAAM,CAAC;IAErC;;;;;;OAMG;gBACS,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM;CAY1E"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error types for the remote-browser capability-gating flow.
|
|
3
|
+
*
|
|
4
|
+
* See `/plans/realtime/realtime-bridges-architecture.md` §4d-i — the Remote Browser channel is built
|
|
5
|
+
* exactly like the bridge subsystem (registry table + base driver + EngineBase/Engine pair +
|
|
6
|
+
* pluggable backends), with the same two-layer capability gating. The engine checks a provider's
|
|
7
|
+
* `SupportedFeatures` flag BEFORE calling an optional driver method; this error is the
|
|
8
|
+
* **defense-in-depth** layer that fires when a feature is claimed in metadata but the concrete driver
|
|
9
|
+
* never implemented it (or a caller skipped the metadata gate). Metadata says "don't call this"; the
|
|
10
|
+
* throw means the code refuses to pretend a capability exists.
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Thrown when a capability-gated remote-browser feature is invoked on a driver that does not support it.
|
|
14
|
+
*
|
|
15
|
+
* Two distinct failure modes both surface as this error:
|
|
16
|
+
* 1. A `BaseRemoteBrowserProvider` **virtual** method (e.g. `GetLiveViewUrl`, `StartScreencast`) was
|
|
17
|
+
* called but the concrete driver did not override the base implementation — the base throws this.
|
|
18
|
+
* 2. The driver's `RequireFeature(...)` defense-in-depth guard found the matching
|
|
19
|
+
* `IRemoteBrowserProviderFeatures` flag false/omitted — the metadata claims the feature is off, so
|
|
20
|
+
* the call must not proceed.
|
|
21
|
+
*
|
|
22
|
+
* Carrying both the `FeatureName` and the `ProviderName` makes the loud failure actionable: it points
|
|
23
|
+
* at exactly which capability flag lied (or which driver method is missing) for which backend.
|
|
24
|
+
*/
|
|
25
|
+
export class RemoteBrowserCapabilityNotSupportedError extends Error {
|
|
26
|
+
/**
|
|
27
|
+
* Constructs a {@link RemoteBrowserCapabilityNotSupportedError}.
|
|
28
|
+
*
|
|
29
|
+
* @param featureName The unsupported feature / method name (an `IRemoteBrowserProviderFeatures` key by convention).
|
|
30
|
+
* @param providerName The backend the call targeted (e.g. `'Browserbase'`, `'Steel'`).
|
|
31
|
+
* @param message Optional override for the human-readable message; a sensible default is built from the two names.
|
|
32
|
+
*/
|
|
33
|
+
constructor(featureName, providerName, message) {
|
|
34
|
+
super(message ??
|
|
35
|
+
`Remote browser capability '${featureName}' is not supported by provider '${providerName}'. ` +
|
|
36
|
+
`Either the provider's SupportedFeatures does not enable it, or its driver does not implement it.`);
|
|
37
|
+
this.name = 'RemoteBrowserCapabilityNotSupportedError';
|
|
38
|
+
this.FeatureName = featureName;
|
|
39
|
+
this.ProviderName = providerName;
|
|
40
|
+
// Restore the prototype chain — required when extending built-ins under ES2015+ down-compilation.
|
|
41
|
+
Object.setPrototypeOf(this, RemoteBrowserCapabilityNotSupportedError.prototype);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=capability-errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capability-errors.js","sourceRoot":"","sources":["../src/capability-errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH;;;;;;;;;;;;GAYG;AACH,MAAM,OAAO,wCAAyC,SAAQ,KAAK;IAe/D;;;;;;OAMG;IACH,YAAY,WAAmB,EAAE,YAAoB,EAAE,OAAgB;QACnE,KAAK,CACD,OAAO;YACH,8BAA8B,WAAW,mCAAmC,YAAY,KAAK;gBACzF,kGAAkG,CAC7G,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,0CAA0C,CAAC;QACvD,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;QACjC,kGAAkG;QAClG,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,wCAAwC,CAAC,SAAS,CAAC,CAAC;IACpF,CAAC;CACJ"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { IRemoteBrowserProviderFeatures } from './remote-browser-features.js';
|
|
2
|
+
/**
|
|
3
|
+
* How control of the remote browser is shared between the agent and humans — a per-provider default
|
|
4
|
+
* (`MJ: AI Remote Browser Providers.DefaultControlMode`) that the `RemoteBrowserChannel` config
|
|
5
|
+
* overrides per-channel and at runtime.
|
|
6
|
+
*
|
|
7
|
+
* This is **distinct from** {@link RemoteBrowserControlStrategy}: the *mode* is the human/agent
|
|
8
|
+
* sharing policy, the *strategy* is the mechanism by which the agent decides what to do.
|
|
9
|
+
*
|
|
10
|
+
* - `AgentOnly` — only the agent drives; no human takeover (e.g. a hands-off sales demo).
|
|
11
|
+
* - `ViewOnly` — the agent drives while humans **watch** the live view but cannot take the wheel.
|
|
12
|
+
* Requires the backend's `LiveView` capability.
|
|
13
|
+
* - `Collaborative` — a human can **grab the wheel** (e.g. a trainer agent: demonstrate a task, then
|
|
14
|
+
* "your turn, try X"). Requires both `LiveView` (to watch) and `HumanTakeover` (to drive).
|
|
15
|
+
*
|
|
16
|
+
* @see `/plans/realtime/realtime-bridges-architecture.md` §4d-i.
|
|
17
|
+
*/
|
|
18
|
+
export type RemoteBrowserControlMode = 'AgentOnly' | 'ViewOnly' | 'Collaborative';
|
|
19
|
+
/**
|
|
20
|
+
* The mechanism by which the agent decides *what to click/type/navigate* — a pluggable strategy
|
|
21
|
+
* gated by capability, orthogonal to the {@link RemoteBrowserControlMode}.
|
|
22
|
+
*
|
|
23
|
+
* - `ComputerUse` — MJ's own perception→action loop over the universal CDP substrate
|
|
24
|
+
* (`@memberjunction/computer-use`). The default; works on every backend that exposes
|
|
25
|
+
* `RawCdpControl`. The right fit for a realtime co-agent that is already a powerful brain emitting
|
|
26
|
+
* tool calls while it talks.
|
|
27
|
+
* - `NativeAI` — delegate high-level intents to the backend's own first-party AI-control harness
|
|
28
|
+
* (e.g. Browserbase Stagehand, Hyperbrowser agent). An optional accelerator for heavy, robust
|
|
29
|
+
* autonomous automation; it runs its own model loop, so it is offered, never the default. Requires
|
|
30
|
+
* the backend's `NativeAIControl` capability.
|
|
31
|
+
*
|
|
32
|
+
* @see `/plans/realtime/realtime-bridges-architecture.md` §4d-i ("Control is a pluggable STRATEGY").
|
|
33
|
+
*/
|
|
34
|
+
export type RemoteBrowserControlStrategy = 'ComputerUse' | 'NativeAI';
|
|
35
|
+
/**
|
|
36
|
+
* Determines whether a {@link RemoteBrowserControlMode} is valid given a backend's capabilities.
|
|
37
|
+
*
|
|
38
|
+
* A mode is only valid when the backend supports the capabilities it requires:
|
|
39
|
+
* - `AgentOnly` — always valid (the agent drives; no viewing/takeover prerequisite).
|
|
40
|
+
* - `ViewOnly` — requires `LiveView` (humans must be able to watch).
|
|
41
|
+
* - `Collaborative` — requires `LiveView` **and** `HumanTakeover` (humans watch *and* can take over).
|
|
42
|
+
*
|
|
43
|
+
* @param mode The control mode to validate.
|
|
44
|
+
* @param features The backend's capability flags.
|
|
45
|
+
* @returns `true` when the backend can support the mode, `false` otherwise.
|
|
46
|
+
*/
|
|
47
|
+
export declare function isControlModeSupported(mode: RemoteBrowserControlMode, features: IRemoteBrowserProviderFeatures): boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Resolves which {@link RemoteBrowserControlStrategy} the engine should use for a backend, honoring an
|
|
50
|
+
* optional caller preference.
|
|
51
|
+
*
|
|
52
|
+
* **Precedence (highest to lowest):**
|
|
53
|
+
* 1. **`NativeAI`** — chosen *only* when the backend advertises `NativeAIControl` **and** the caller
|
|
54
|
+
* did not explicitly pin `ComputerUse`. (A caller preference of `'NativeAI'` is honored only if the
|
|
55
|
+
* backend actually supports it; an explicit `'ComputerUse'` always suppresses native delegation.)
|
|
56
|
+
* 2. **`ComputerUse`** — the universal default, chosen whenever the backend exposes the
|
|
57
|
+
* `RawCdpControl` substrate and native control was not selected above.
|
|
58
|
+
* 3. **`ComputerUse`** — also the fallback when neither flag is set, because CDP-connect is the one
|
|
59
|
+
* primitive every backend is expected to provide; emitting `ComputerUse` lets the caller surface a
|
|
60
|
+
* clear downstream error if the backend genuinely cannot be driven, rather than this helper
|
|
61
|
+
* inventing an unsupported strategy.
|
|
62
|
+
*
|
|
63
|
+
* @param features The backend's capability flags.
|
|
64
|
+
* @param preferred An optional caller preference; `'ComputerUse'` pins the universal loop and
|
|
65
|
+
* suppresses native delegation even when the backend supports it.
|
|
66
|
+
* @returns The resolved control strategy.
|
|
67
|
+
*/
|
|
68
|
+
export declare function resolveControlStrategy(features: IRemoteBrowserProviderFeatures, preferred?: RemoteBrowserControlStrategy): RemoteBrowserControlStrategy;
|
|
69
|
+
//# sourceMappingURL=control.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"control.d.ts","sourceRoot":"","sources":["../src/control.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,8BAA8B,EAAE,MAAM,2BAA2B,CAAC;AAE3E;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,wBAAwB,GAAG,WAAW,GAAG,UAAU,GAAG,eAAe,CAAC;AAElF;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,4BAA4B,GAAG,aAAa,GAAG,UAAU,CAAC;AAEtE;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CAClC,IAAI,EAAE,wBAAwB,EAC9B,QAAQ,EAAE,8BAA8B,GACzC,OAAO,CAYT;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,sBAAsB,CAClC,QAAQ,EAAE,8BAA8B,EACxC,SAAS,CAAC,EAAE,4BAA4B,GACzC,4BAA4B,CAK9B"}
|