agl 22.0.4 → 24.0.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.
Files changed (44) hide show
  1. package/changelog.md +21 -0
  2. package/dist_serve/bundle.js +2418 -2408
  3. package/dist_serve/bundle.js.map +1 -0
  4. package/dist_ts/00_commitinfo_data.js +1 -1
  5. package/dist_ts/classes.authstore.js +2 -2
  6. package/dist_ts/classes.browserresourcehost.d.ts +1 -0
  7. package/dist_ts/classes.browserresourcehost.js +7 -1
  8. package/dist_ts/classes.controller.d.ts +37 -5
  9. package/dist_ts/classes.controller.js +1491 -249
  10. package/dist_ts/classes.flexservice.d.ts +5 -0
  11. package/dist_ts/classes.flexservice.js +131 -4
  12. package/dist_ts/classes.opencodeclient.d.ts +2 -0
  13. package/dist_ts/classes.opencodeclient.js +23 -1
  14. package/dist_ts/classes.validation.d.ts +9 -1
  15. package/dist_ts/classes.validation.js +62 -7
  16. package/dist_ts/interfaces.flexipc.d.ts +18 -1
  17. package/dist_ts/interfaces.flexipc.js +42 -8
  18. package/dist_ts_interfaces/browsertransport.d.ts +72 -0
  19. package/dist_ts_interfaces/browsertransport.js +47 -0
  20. package/dist_ts_interfaces/index.d.ts +1 -0
  21. package/dist_ts_interfaces/index.js +2 -1
  22. package/dist_ts_interfaces/interfaces.d.ts +42 -7
  23. package/dist_ts_interfaces/interfaces.js +5 -3
  24. package/dist_ts_interfaces/requests.d.ts +20 -21
  25. package/package.json +7 -7
  26. package/readme.md +12 -2
  27. package/ts/00_commitinfo_data.ts +1 -1
  28. package/ts/classes.authstore.ts +1 -1
  29. package/ts/classes.browserresourcehost.ts +7 -0
  30. package/ts/classes.controller.ts +1960 -305
  31. package/ts/classes.flexservice.ts +132 -2
  32. package/ts/classes.opencodeclient.ts +19 -0
  33. package/ts/classes.validation.ts +77 -6
  34. package/ts/interfaces.flexipc.ts +65 -7
  35. package/ts_interfaces/browsertransport.ts +126 -0
  36. package/ts_interfaces/index.ts +1 -0
  37. package/ts_interfaces/interfaces.ts +46 -11
  38. package/ts_interfaces/requests.ts +23 -30
  39. package/ts_web/00_commitinfo_data.ts +1 -1
  40. package/ts_web/classes.browserviewtransport.ts +532 -0
  41. package/ts_web/classes.controllersocketclient.ts +119 -29
  42. package/ts_web/elements.harnesscontrollerapp.ts +1727 -287
  43. package/ts_web/index.ts +1 -0
  44. package/ts_web/plugins.ts +2 -0
@@ -0,0 +1,47 @@
1
+ export const controllerBrowserTransportProtocol = 'agl-browser-v24';
2
+ export const controllerBrowserTransportEventContentType = 'application/vnd.agl.browser-events.v24';
3
+ export const controllerBrowserTransportOperationContentType = 'application/vnd.agl.browser-operations.v24';
4
+ export const controllerBrowserTransportMaximumJsonBytes = 64 * 1024;
5
+ export const controllerBrowserTransportMaximumFrameBytes = 4 * 1024 * 1024;
6
+ export const controllerBrowserTransportPairOpenTimeoutMs = 9_000;
7
+ export const controllerBrowserTransportRecoveryGraceMs = 15_000;
8
+ export const controllerBrowserTransportMaximumRecoveryAttempts = 3;
9
+ export const controllerBrowserTransportMaximumPendingOperations = 64;
10
+ export const controllerBrowserTransportMaximumQueuedOperationBytes = 256 * 1024;
11
+ export const controllerBrowserTransportMaximumActiveAcknowledgements = 16;
12
+ export const controllerBrowserTransportMaximumPendingEvents = 16;
13
+ export const controllerBrowserTransportMaximumPendingEventBytes = 16 * 1024 * 1024;
14
+ export class ControllerBrowserTransportProtocolError extends Error {
15
+ constructor(messageArg, optionsArg) {
16
+ super(messageArg, optionsArg);
17
+ this.name = 'ControllerBrowserTransportProtocolError';
18
+ }
19
+ }
20
+ const textEncoder = new TextEncoder();
21
+ const textDecoder = new TextDecoder('utf-8', { fatal: true });
22
+ export const encodeControllerBrowserTransportPacket = (packetArg) => {
23
+ let serialized;
24
+ try {
25
+ serialized = JSON.stringify(packetArg);
26
+ }
27
+ catch (errorArg) {
28
+ throw new ControllerBrowserTransportProtocolError('The browser transport packet is not JSON serializable.', { cause: errorArg });
29
+ }
30
+ const bytes = textEncoder.encode(serialized);
31
+ if (bytes.byteLength > controllerBrowserTransportMaximumJsonBytes) {
32
+ throw new ControllerBrowserTransportProtocolError('The browser transport packet exceeds the JSON byte limit.');
33
+ }
34
+ return bytes;
35
+ };
36
+ export const decodeControllerBrowserTransportPacket = (bytesArg) => {
37
+ if (bytesArg.byteLength > controllerBrowserTransportMaximumJsonBytes) {
38
+ throw new ControllerBrowserTransportProtocolError('The browser transport packet exceeds the JSON byte limit.');
39
+ }
40
+ try {
41
+ return JSON.parse(textDecoder.decode(bytesArg));
42
+ }
43
+ catch (errorArg) {
44
+ throw new ControllerBrowserTransportProtocolError('The browser transport packet is not valid UTF-8 JSON.', { cause: errorArg });
45
+ }
46
+ };
47
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnJvd3NlcnRyYW5zcG9ydC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzX2ludGVyZmFjZXMvYnJvd3NlcnRyYW5zcG9ydC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFNQSxNQUFNLENBQUMsTUFBTSxrQ0FBa0MsR0FBRyxpQkFBMEIsQ0FBQztBQUM3RSxNQUFNLENBQUMsTUFBTSwwQ0FBMEMsR0FDckQsd0NBQWlELENBQUM7QUFDcEQsTUFBTSxDQUFDLE1BQU0sOENBQThDLEdBQ3pELDRDQUFxRCxDQUFDO0FBQ3hELE1BQU0sQ0FBQyxNQUFNLDBDQUEwQyxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUM7QUFDcEUsTUFBTSxDQUFDLE1BQU0sMkNBQTJDLEdBQUcsQ0FBQyxHQUFHLElBQUksR0FBRyxJQUFJLENBQUM7QUFDM0UsTUFBTSxDQUFDLE1BQU0sMkNBQTJDLEdBQUcsS0FBSyxDQUFDO0FBQ2pFLE1BQU0sQ0FBQyxNQUFNLHlDQUF5QyxHQUFHLE1BQU0sQ0FBQztBQUNoRSxNQUFNLENBQUMsTUFBTSxpREFBaUQsR0FBRyxDQUFDLENBQUM7QUFDbkUsTUFBTSxDQUFDLE1BQU0sa0RBQWtELEdBQUcsRUFBRSxDQUFDO0FBQ3JFLE1BQU0sQ0FBQyxNQUFNLHFEQUFxRCxHQUFHLEdBQUcsR0FBRyxJQUFJLENBQUM7QUFDaEYsTUFBTSxDQUFDLE1BQU0sdURBQXVELEdBQUcsRUFBRSxDQUFDO0FBQzFFLE1BQU0sQ0FBQyxNQUFNLDhDQUE4QyxHQUFHLEVBQUUsQ0FBQztBQUNqRSxNQUFNLENBQUMsTUFBTSxrREFBa0QsR0FBRyxFQUFFLEdBQUcsSUFBSSxHQUFHLElBQUksQ0FBQztBQTREbkYsTUFBTSxPQUFPLHVDQUF3QyxTQUFRLEtBQUs7SUFDaEUsWUFBWSxVQUFrQixFQUFFLFVBQXlCO1FBQ3ZELEtBQUssQ0FBQyxVQUFVLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFDOUIsSUFBSSxDQUFDLElBQUksR0FBRyx5Q0FBeUMsQ0FBQztJQUN4RCxDQUFDO0NBQ0Y7QUFFRCxNQUFNLFdBQVcsR0FBRyxJQUFJLFdBQVcsRUFBRSxDQUFDO0FBQ3RDLE1BQU0sV0FBVyxHQUFHLElBQUksV0FBVyxDQUFDLE9BQU8sRUFBRSxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO0FBRTlELE1BQU0sQ0FBQyxNQUFNLHNDQUFzQyxHQUFHLENBQ3BELFNBQTBFLEVBQzlELEVBQUU7SUFDZCxJQUFJLFVBQWtCLENBQUM7SUFDdkIsSUFBSSxDQUFDO1FBQ0gsVUFBVSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDekMsQ0FBQztJQUFDLE9BQU8sUUFBUSxFQUFFLENBQUM7UUFDbEIsTUFBTSxJQUFJLHVDQUF1QyxDQUMvQyx3REFBd0QsRUFDeEQsRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLENBQ3BCLENBQUM7SUFDSixDQUFDO0lBQ0QsTUFBTSxLQUFLLEdBQUcsV0FBVyxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUM3QyxJQUFJLEtBQUssQ0FBQyxVQUFVLEdBQUcsMENBQTBDLEVBQUUsQ0FBQztRQUNsRSxNQUFNLElBQUksdUNBQXVDLENBQy9DLDJEQUEyRCxDQUM1RCxDQUFDO0lBQ0osQ0FBQztJQUNELE9BQU8sS0FBSyxDQUFDO0FBQ2YsQ0FBQyxDQUFDO0FBRUYsTUFBTSxDQUFDLE1BQU0sc0NBQXNDLEdBQUcsQ0FBQyxRQUFvQixFQUFXLEVBQUU7SUFDdEYsSUFBSSxRQUFRLENBQUMsVUFBVSxHQUFHLDBDQUEwQyxFQUFFLENBQUM7UUFDckUsTUFBTSxJQUFJLHVDQUF1QyxDQUMvQywyREFBMkQsQ0FDNUQsQ0FBQztJQUNKLENBQUM7SUFDRCxJQUFJLENBQUM7UUFDSCxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO0lBQ2xELENBQUM7SUFBQyxPQUFPLFFBQVEsRUFBRSxDQUFDO1FBQ2xCLE1BQU0sSUFBSSx1Q0FBdUMsQ0FDL0MsdURBQXVELEVBQ3ZELEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxDQUNwQixDQUFDO0lBQ0osQ0FBQztBQUNILENBQUMsQ0FBQyJ9
@@ -1,2 +1,3 @@
1
1
  export * from './interfaces.js';
2
+ export * from './browsertransport.js';
2
3
  export * from './requests.js';
@@ -1,3 +1,4 @@
1
1
  export * from './interfaces.js';
2
+ export * from './browsertransport.js';
2
3
  export * from './requests.js';
3
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90c19pbnRlcmZhY2VzL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGNBQWMsaUJBQWlCLENBQUM7QUFDaEMsY0FBYyxlQUFlLENBQUMifQ==
4
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90c19pbnRlcmZhY2VzL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGNBQWMsaUJBQWlCLENBQUM7QUFDaEMsY0FBYyx1QkFBdUIsQ0FBQztBQUN0QyxjQUFjLGVBQWUsQ0FBQyJ9
@@ -1,9 +1,9 @@
1
- import * as plugins from './plugins.js';
2
- export declare const controllerProtocolVersion: 22;
1
+ export declare const controllerProtocolVersion: 24;
3
2
  export declare const controllerUpgradeManagementVersion: 2;
4
3
  export declare const controllerPackageName: "agl";
5
4
  export declare const controllerMaxToolEventBytes: number;
6
5
  export declare const controllerMaxLiveMessageEventBytes: number;
6
+ export declare const controllerLiveMessageDeltaTargetBytes: number;
7
7
  export declare const controllerInitialMessageBundleLimit = 20;
8
8
  export declare const controllerMaximumMessageBundles = 200;
9
9
  export declare const controllerMaximumTranscriptBytes: number;
@@ -189,6 +189,8 @@ export interface IControllerBrowserTabState {
189
189
  streaming: boolean;
190
190
  }
191
191
  export interface IControllerBrowserViewState {
192
+ /** Monotonic for the complete lifetime of one browser view. */
193
+ revision: number;
192
194
  status: 'stopped' | 'starting' | 'running' | 'stopping';
193
195
  activeTabId: string | null;
194
196
  viewportRevision: number;
@@ -201,7 +203,7 @@ export interface IControllerBrowserViewState {
201
203
  tabId?: string;
202
204
  };
203
205
  }
204
- export interface IControllerBrowserFrame<TDirection extends plugins.typedrequestInterfaces.TVirtualStreamDirection> {
206
+ export interface IControllerBrowserFrameMetadata {
205
207
  tabId: string;
206
208
  sequence: number;
207
209
  generation: number;
@@ -220,14 +222,17 @@ export interface IControllerBrowserFrame<TDirection extends plugins.typedrequest
220
222
  scrollOffsetY: number;
221
223
  timestamp?: number;
222
224
  };
223
- dataStream: plugins.typedrequestInterfaces.TVirtualStream<TDirection>;
225
+ dataByteLength: number;
226
+ }
227
+ export interface IControllerBrowserFrame extends Omit<IControllerBrowserFrameMetadata, 'dataByteLength'> {
228
+ data: Uint8Array;
224
229
  }
225
- export type TControllerBrowserViewEvent<TDirection extends plugins.typedrequestInterfaces.TVirtualStreamDirection> = {
230
+ export type TControllerBrowserViewEvent = {
226
231
  type: 'state';
227
232
  state: IControllerBrowserViewState;
228
233
  } | {
229
234
  type: 'frame';
230
- frame: IControllerBrowserFrame<TDirection>;
235
+ frame: IControllerBrowserFrame;
231
236
  } | {
232
237
  type: 'error';
233
238
  error: {
@@ -453,6 +458,32 @@ export interface IControllerTextUpdate {
453
458
  revision: number;
454
459
  streamEpoch: number;
455
460
  }
461
+ export interface IControllerReasoningDelta {
462
+ sessionId: IControllerRuntimeId;
463
+ messageId: IControllerRuntimeId;
464
+ partId: IControllerRuntimeId;
465
+ delta: string;
466
+ baseTextUtf8Bytes: number;
467
+ textUtf8Bytes: number;
468
+ /** Authoritative source coordinates; required for Flex and absent for OpenCode. */
469
+ order?: IControllerTranscriptOrder;
470
+ sourceUpdatedAt: number;
471
+ revision: number;
472
+ streamEpoch: number;
473
+ }
474
+ export interface IControllerTextDelta {
475
+ sessionId: IControllerRuntimeId;
476
+ messageId: IControllerRuntimeId;
477
+ partId: IControllerRuntimeId;
478
+ delta: string;
479
+ baseTextUtf8Bytes: number;
480
+ textUtf8Bytes: number;
481
+ /** Authoritative source coordinates; required for Flex and absent for OpenCode. */
482
+ order?: IControllerTranscriptOrder;
483
+ sourceUpdatedAt: number;
484
+ revision: number;
485
+ streamEpoch: number;
486
+ }
456
487
  export interface IControllerToolStreamCursor {
457
488
  streamEpoch: number;
458
489
  revision: number;
@@ -718,7 +749,7 @@ export interface IControllerModelRefreshJob {
718
749
  * client validates incoming events against this list at runtime, so a type
719
750
  * added here is automatically deliverable — the two cannot drift apart.
720
751
  */
721
- export declare const controllerEventTypes: readonly ["sessions.changed", "session.changed", "session.draft.changed", "session.history.changed", "session.tool.updated", "session.reasoning.updated", "session.text.updated", "permissions.changed", "harness.changed", "projects.changed", "settings.changed", "sessiongroups.changed", "resources.changed", "terminals.changed", "upgrade.changed"];
752
+ export declare const controllerEventTypes: readonly ["sessions.changed", "session.changed", "session.draft.changed", "session.history.changed", "session.tool.updated", "session.reasoning.updated", "session.reasoning.delta", "session.text.updated", "session.text.delta", "permissions.changed", "harness.changed", "projects.changed", "settings.changed", "sessiongroups.changed", "resources.changed", "terminals.changed", "upgrade.changed"];
722
753
  export type TControllerEventType = (typeof controllerEventTypes)[number];
723
754
  export interface IControllerEvent {
724
755
  type: TControllerEventType;
@@ -733,8 +764,12 @@ export interface IControllerEvent {
733
764
  toolExecution?: IControllerToolExecution;
734
765
  /** Present only on a live OpenCode or Flex reasoning snapshot. */
735
766
  reasoningUpdate?: IControllerReasoningUpdate;
767
+ /** Present only on an exact live OpenCode or Flex reasoning delta. */
768
+ reasoningDelta?: IControllerReasoningDelta;
736
769
  /** Present only on a live OpenCode or Flex text snapshot. */
737
770
  textUpdate?: IControllerTextUpdate;
771
+ /** Present only on an exact live OpenCode or Flex text delta. */
772
+ textDelta?: IControllerTextDelta;
738
773
  /** Present only on a session.draft.changed event. */
739
774
  sessionDraftUpdate?: IControllerSessionDraftUpdate;
740
775
  /** Ordered harness stream barrier carried by harness.changed. */
@@ -1,9 +1,9 @@
1
- import * as plugins from './plugins.js';
2
- export const controllerProtocolVersion = 22;
1
+ export const controllerProtocolVersion = 24;
3
2
  export const controllerUpgradeManagementVersion = 2;
4
3
  export const controllerPackageName = 'agl';
5
4
  export const controllerMaxToolEventBytes = 48 * 1024;
6
5
  export const controllerMaxLiveMessageEventBytes = 128 * 1024;
6
+ export const controllerLiveMessageDeltaTargetBytes = 16 * 1024;
7
7
  export const controllerInitialMessageBundleLimit = 20;
8
8
  export const controllerMaximumMessageBundles = 200;
9
9
  export const controllerMaximumTranscriptBytes = 512 * 1024;
@@ -34,7 +34,9 @@ export const controllerEventTypes = [
34
34
  'session.history.changed',
35
35
  'session.tool.updated',
36
36
  'session.reasoning.updated',
37
+ 'session.reasoning.delta',
37
38
  'session.text.updated',
39
+ 'session.text.delta',
38
40
  'permissions.changed',
39
41
  'harness.changed',
40
42
  'projects.changed',
@@ -44,4 +46,4 @@ export const controllerEventTypes = [
44
46
  'terminals.changed',
45
47
  'upgrade.changed',
46
48
  ];
47
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW50ZXJmYWNlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzX2ludGVyZmFjZXMvaW50ZXJmYWNlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQUV4QyxNQUFNLENBQUMsTUFBTSx5QkFBeUIsR0FBRyxFQUFXLENBQUM7QUFDckQsTUFBTSxDQUFDLE1BQU0sa0NBQWtDLEdBQUcsQ0FBVSxDQUFDO0FBQzdELE1BQU0sQ0FBQyxNQUFNLHFCQUFxQixHQUFHLEtBQWMsQ0FBQztBQUNwRCxNQUFNLENBQUMsTUFBTSwyQkFBMkIsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDO0FBQ3JELE1BQU0sQ0FBQyxNQUFNLGtDQUFrQyxHQUFHLEdBQUcsR0FBRyxJQUFJLENBQUM7QUFDN0QsTUFBTSxDQUFDLE1BQU0sbUNBQW1DLEdBQUcsRUFBRSxDQUFDO0FBQ3RELE1BQU0sQ0FBQyxNQUFNLCtCQUErQixHQUFHLEdBQUcsQ0FBQztBQUNuRCxNQUFNLENBQUMsTUFBTSxnQ0FBZ0MsR0FBRyxHQUFHLEdBQUcsSUFBSSxDQUFDO0FBQzNELE1BQU0sQ0FBQyxNQUFNLCtCQUErQixHQUMxQyw4REFBdUUsQ0FBQztBQUMxRSxNQUFNLENBQUMsTUFBTSwyQkFBMkIsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDO0FBQ3JELE1BQU0sQ0FBQyxNQUFNLDZCQUE2QixHQUFHLENBQUMsQ0FBQztBQUMvQyxNQUFNLENBQUMsTUFBTSxpQ0FBaUMsR0FBRyxFQUFFLEdBQUcsSUFBSSxHQUFHLElBQUksQ0FBQztBQUNsRSxNQUFNLENBQUMsTUFBTSxzQ0FBc0MsR0FBRyxFQUFFLEdBQUcsSUFBSSxHQUFHLElBQUksQ0FBQztBQUN2RSxNQUFNLENBQUMsTUFBTSx3Q0FBd0MsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDO0FBRWxFLE1BQU0sQ0FBQyxNQUFNLG9CQUFvQixHQUFHLENBQUMsVUFBVSxFQUFFLE1BQU0sRUFBRSxZQUFZLENBQVUsQ0FBQztBQUNoRixNQUFNLENBQUMsTUFBTSwyQkFBMkIsR0FBRyxDQUFDLFVBQVUsRUFBRSxNQUFNLENBQVUsQ0FBQztBQW1CekUsNkVBQTZFO0FBQzdFLE1BQU0sQ0FBQyxNQUFNLHNCQUFzQixHQUFHLENBQUMsWUFBa0MsRUFBVSxFQUFFLENBQ25GLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxZQUFZLENBQUMsU0FBUyxFQUFFLFlBQVksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO0FBVWxFOzs7R0FHRztBQUNILE1BQU0sQ0FBQyxNQUFNLHlCQUF5QixHQUFHLENBQUMsU0FBUyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsTUFBTSxDQUFVLENBQUM7QUFvdEJ0Rjs7OztHQUlHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sb0JBQW9CLEdBQUc7SUFDbEMsa0JBQWtCO0lBQ2xCLGlCQUFpQjtJQUNqQix1QkFBdUI7SUFDdkIseUJBQXlCO0lBQ3pCLHNCQUFzQjtJQUN0QiwyQkFBMkI7SUFDM0Isc0JBQXNCO0lBQ3RCLHFCQUFxQjtJQUNyQixpQkFBaUI7SUFDakIsa0JBQWtCO0lBQ2xCLGtCQUFrQjtJQUNsQix1QkFBdUI7SUFDdkIsbUJBQW1CO0lBQ25CLG1CQUFtQjtJQUNuQixpQkFBaUI7Q0FDVCxDQUFDIn0=
49
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW50ZXJmYWNlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzX2ludGVyZmFjZXMvaW50ZXJmYWNlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxNQUFNLENBQUMsTUFBTSx5QkFBeUIsR0FBRyxFQUFXLENBQUM7QUFDckQsTUFBTSxDQUFDLE1BQU0sa0NBQWtDLEdBQUcsQ0FBVSxDQUFDO0FBQzdELE1BQU0sQ0FBQyxNQUFNLHFCQUFxQixHQUFHLEtBQWMsQ0FBQztBQUNwRCxNQUFNLENBQUMsTUFBTSwyQkFBMkIsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDO0FBQ3JELE1BQU0sQ0FBQyxNQUFNLGtDQUFrQyxHQUFHLEdBQUcsR0FBRyxJQUFJLENBQUM7QUFDN0QsTUFBTSxDQUFDLE1BQU0scUNBQXFDLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQztBQUMvRCxNQUFNLENBQUMsTUFBTSxtQ0FBbUMsR0FBRyxFQUFFLENBQUM7QUFDdEQsTUFBTSxDQUFDLE1BQU0sK0JBQStCLEdBQUcsR0FBRyxDQUFDO0FBQ25ELE1BQU0sQ0FBQyxNQUFNLGdDQUFnQyxHQUFHLEdBQUcsR0FBRyxJQUFJLENBQUM7QUFDM0QsTUFBTSxDQUFDLE1BQU0sK0JBQStCLEdBQzFDLDhEQUF1RSxDQUFDO0FBQzFFLE1BQU0sQ0FBQyxNQUFNLDJCQUEyQixHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUM7QUFDckQsTUFBTSxDQUFDLE1BQU0sNkJBQTZCLEdBQUcsQ0FBQyxDQUFDO0FBQy9DLE1BQU0sQ0FBQyxNQUFNLGlDQUFpQyxHQUFHLEVBQUUsR0FBRyxJQUFJLEdBQUcsSUFBSSxDQUFDO0FBQ2xFLE1BQU0sQ0FBQyxNQUFNLHNDQUFzQyxHQUFHLEVBQUUsR0FBRyxJQUFJLEdBQUcsSUFBSSxDQUFDO0FBQ3ZFLE1BQU0sQ0FBQyxNQUFNLHdDQUF3QyxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUM7QUFFbEUsTUFBTSxDQUFDLE1BQU0sb0JBQW9CLEdBQUcsQ0FBQyxVQUFVLEVBQUUsTUFBTSxFQUFFLFlBQVksQ0FBVSxDQUFDO0FBQ2hGLE1BQU0sQ0FBQyxNQUFNLDJCQUEyQixHQUFHLENBQUMsVUFBVSxFQUFFLE1BQU0sQ0FBVSxDQUFDO0FBbUJ6RSw2RUFBNkU7QUFDN0UsTUFBTSxDQUFDLE1BQU0sc0JBQXNCLEdBQUcsQ0FBQyxZQUFrQyxFQUFVLEVBQUUsQ0FDbkYsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxTQUFTLEVBQUUsWUFBWSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7QUFVbEU7OztHQUdHO0FBQ0gsTUFBTSxDQUFDLE1BQU0seUJBQXlCLEdBQUcsQ0FBQyxTQUFTLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxNQUFNLENBQVUsQ0FBQztBQWt2QnRGOzs7O0dBSUc7QUFDSCxNQUFNLENBQUMsTUFBTSxvQkFBb0IsR0FBRztJQUNsQyxrQkFBa0I7SUFDbEIsaUJBQWlCO0lBQ2pCLHVCQUF1QjtJQUN2Qix5QkFBeUI7SUFDekIsc0JBQXNCO0lBQ3RCLDJCQUEyQjtJQUMzQix5QkFBeUI7SUFDekIsc0JBQXNCO0lBQ3RCLG9CQUFvQjtJQUNwQixxQkFBcUI7SUFDckIsaUJBQWlCO0lBQ2pCLGtCQUFrQjtJQUNsQixrQkFBa0I7SUFDbEIsdUJBQXVCO0lBQ3ZCLG1CQUFtQjtJQUNuQixtQkFBbUI7SUFDbkIsaUJBQWlCO0NBQ1QsQ0FBQyJ9
@@ -1,5 +1,5 @@
1
1
  import * as plugins from './plugins.js';
2
- import type { IControllerEvent, IControllerMessageBundle, IControllerMessagePage, TControllerModelChoice, TControllerModelOption, IControllerPathSuggestion, IControllerProject, TControllerResource, TControllerResourceKind, IControllerBrowserViewState, TControllerBrowserViewEvent, TControllerBrowserViewOperation, IControllerProvider, IControllerProviderAccountRateLimits, IControllerProviderConnection, IControllerProviderLogin, IControllerModelRefreshJob, IControllerRuntimeId, IControllerSession, IControllerSessionDraft, IControllerDraftAttachment, IControllerSessionGroup, IControllerSessionLayout, IControllerTerminal, TControllerTerminalId, IControllerSlashListResult, TControllerSlashExecuteResult, IControllerSessionDetail, IControllerSessionAuxiliary, IControllerSessionScratchpad, IControllerIntelligenceExchange, IControllerSettings, IControllerStatus, IControllerSystemMetrics, TControllerAuthState, TControllerPermissionReply, TControllerSessionHarnessId, TControllerSessionId } from './interfaces.js';
2
+ import type { IControllerEvent, IControllerMessageBundle, IControllerMessagePage, TControllerModelChoice, TControllerModelOption, IControllerPathSuggestion, IControllerProject, TControllerResource, TControllerResourceKind, IControllerBrowserViewState, IControllerProvider, IControllerProviderAccountRateLimits, IControllerProviderConnection, IControllerProviderLogin, IControllerModelRefreshJob, IControllerRuntimeId, IControllerSession, IControllerSessionDraft, IControllerDraftAttachment, IControllerSessionGroup, IControllerSessionLayout, IControllerTerminal, TControllerTerminalId, IControllerSlashListResult, TControllerSlashExecuteResult, IControllerSessionDetail, IControllerSessionAuxiliary, IControllerSessionScratchpad, IControllerIntelligenceExchange, IControllerSettings, IControllerStatus, IControllerSystemMetrics, TControllerAuthState, TControllerPermissionReply, TControllerSessionHarnessId, TControllerSessionId } from './interfaces.js';
3
3
  export interface IReq_ControllerStatus extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_ControllerStatus> {
4
4
  method: 'controller.status';
5
5
  request: Record<string, never>;
@@ -663,6 +663,9 @@ export interface IReq_ControllerBrowserViewOpen extends plugins.typedrequestInte
663
663
  viewId: string;
664
664
  resourceId: string;
665
665
  attachmentRevision: number;
666
+ streamGeneration: number;
667
+ events: plugins.typedrequestInterfaces.TVirtualStream<'receive'>;
668
+ operations: plugins.typedrequestInterfaces.TVirtualStream<'send'>;
666
669
  state: IControllerBrowserViewState;
667
670
  };
668
671
  }
@@ -670,41 +673,37 @@ export interface IReq_ControllerBrowserViewActivate extends plugins.typedrequest
670
673
  method: 'controller.browser.view.activate';
671
674
  request: {
672
675
  viewId: string;
676
+ streamGeneration: number;
673
677
  };
674
678
  response: {
675
679
  activated: true;
676
680
  };
677
681
  }
678
- export interface IReq_ControllerBrowserViewClose extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_ControllerBrowserViewClose> {
679
- method: 'controller.browser.view.close';
682
+ export interface IReq_ControllerBrowserViewRecover extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_ControllerBrowserViewRecover> {
683
+ method: 'controller.browser.view.recover';
680
684
  request: {
681
685
  viewId: string;
686
+ expectedStreamGeneration: number;
682
687
  };
683
688
  response: {
684
- closed: true;
685
- };
686
- }
687
- export interface IReq_ControllerBrowserViewOperate extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_ControllerBrowserViewOperate> {
688
- method: 'controller.browser.view.operate';
689
- request: {
690
689
  viewId: string;
691
- operation: TControllerBrowserViewOperation;
692
- };
693
- response: {
694
- accepted: boolean;
690
+ resourceId: string;
691
+ attachmentRevision: number;
692
+ streamGeneration: number;
693
+ events: plugins.typedrequestInterfaces.TVirtualStream<'receive'>;
694
+ operations: plugins.typedrequestInterfaces.TVirtualStream<'send'>;
695
695
  state: IControllerBrowserViewState;
696
696
  };
697
697
  }
698
- /** Server to client push for one exact human browser view. */
699
- export interface IReq_ControllerBrowserViewEvent extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_ControllerBrowserViewEvent> {
700
- method: 'controller.browser.view.event';
698
+ export interface IReq_ControllerBrowserViewClose extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_ControllerBrowserViewClose> {
699
+ method: 'controller.browser.view.close';
701
700
  request: {
702
701
  viewId: string;
703
- resourceId: string;
704
- attachmentRevision: number;
705
- event: TControllerBrowserViewEvent<'send'>;
702
+ expectedStreamGeneration: number;
703
+ };
704
+ response: {
705
+ closed: boolean;
706
706
  };
707
- response: Record<string, never>;
708
707
  }
709
708
  export interface IReq_ControllerTerminalCreate extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_ControllerTerminalCreate> {
710
709
  method: 'controller.terminal.create';
@@ -803,4 +802,4 @@ export interface IReq_ControllerEvent extends plugins.typedrequestInterfaces.imp
803
802
  received: true;
804
803
  };
805
804
  }
806
- export type TControllerRequest = IReq_ControllerStatus | IReq_ControllerUpgradeLaunch | IReq_ControllerUpgradePrepare | IReq_ControllerUpgradePrepareBegin | IReq_ControllerUpgradeFinalize | IReq_ControllerSystemMetrics | IReq_ControllerAuthState | IReq_ControllerSetupBegin | IReq_ControllerSetupFinish | IReq_ControllerAuthenticationBegin | IReq_ControllerAuthenticationFinish | IReq_ControllerTempPasswordLogin | IReq_ControllerAuthResume | IReq_ControllerProjectList | IReq_ControllerProjectCreate | IReq_ControllerProjectRemove | IReq_ControllerProjectSuggest | IReq_ControllerProviderList | IReq_ControllerProviderConnectionList | IReq_ControllerProviderConnectionActivateOpenCode | IReq_ControllerProviderLoginBegin | IReq_ControllerProviderLoginGet | IReq_ControllerProviderLoginCancel | IReq_ControllerProviderConnectionLogout | IReq_ControllerProviderConnectionRateLimitsGet | IReq_ControllerProviderModelRefreshBegin | IReq_ControllerProviderModelRefreshGet | IReq_ControllerSlashList | IReq_ControllerSlashExecute | IReq_ControllerModelList | IReq_ControllerSettingsGet | IReq_ControllerSettingsUpdate | IReq_ControllerSessionList | IReq_ControllerSessionGet | IReq_ControllerSessionAuxiliaryGet | IReq_ControllerSessionModelUpdate | IReq_ControllerSessionScratchpadSave | IReq_ControllerSessionIntelligenceAsk | IReq_ControllerSessionMessagesPage | IReq_ControllerSessionMessageGet | IReq_ControllerSessionCreate | IReq_ControllerSessionDelete | IReq_ControllerSessionDiscardEmpty | IReq_ControllerSessionDraftGet | IReq_ControllerSessionDraftUpdate | IReq_ControllerSessionSend | IReq_ControllerSessionAbort | IReq_ControllerPermissionReply | IReq_ControllerQuestionReply | IReq_ControllerSessionRename | IReq_ControllerSessionArchive | IReq_ControllerSessionGroupsGet | IReq_ControllerSessionGroupsUpdate | IReq_ControllerSessionYolo | IReq_ControllerResourceList | IReq_ControllerResourceCreate | IReq_ControllerResourceRename | IReq_ControllerResourceAttach | IReq_ControllerResourceDetach | IReq_ControllerResourceRetire | IReq_ControllerResourceStart | IReq_ControllerResourceStop | IReq_ControllerBrowserViewOpen | IReq_ControllerBrowserViewActivate | IReq_ControllerBrowserViewClose | IReq_ControllerBrowserViewOperate | IReq_ControllerTerminalList | IReq_ControllerTerminalCreate | IReq_ControllerTerminalRename | IReq_ControllerTerminalRemove | IReq_ControllerTerminalAttach | IReq_ControllerTerminalDetach | IReq_ControllerTerminalInput | IReq_ControllerTerminalResize | IReq_ControllerTerminalOutput | IReq_ControllerBrowserViewEvent | IReq_ControllerEvent;
805
+ export type TControllerRequest = IReq_ControllerStatus | IReq_ControllerUpgradeLaunch | IReq_ControllerUpgradePrepare | IReq_ControllerUpgradePrepareBegin | IReq_ControllerUpgradeFinalize | IReq_ControllerSystemMetrics | IReq_ControllerAuthState | IReq_ControllerSetupBegin | IReq_ControllerSetupFinish | IReq_ControllerAuthenticationBegin | IReq_ControllerAuthenticationFinish | IReq_ControllerTempPasswordLogin | IReq_ControllerAuthResume | IReq_ControllerProjectList | IReq_ControllerProjectCreate | IReq_ControllerProjectRemove | IReq_ControllerProjectSuggest | IReq_ControllerProviderList | IReq_ControllerProviderConnectionList | IReq_ControllerProviderConnectionActivateOpenCode | IReq_ControllerProviderLoginBegin | IReq_ControllerProviderLoginGet | IReq_ControllerProviderLoginCancel | IReq_ControllerProviderConnectionLogout | IReq_ControllerProviderConnectionRateLimitsGet | IReq_ControllerProviderModelRefreshBegin | IReq_ControllerProviderModelRefreshGet | IReq_ControllerSlashList | IReq_ControllerSlashExecute | IReq_ControllerModelList | IReq_ControllerSettingsGet | IReq_ControllerSettingsUpdate | IReq_ControllerSessionList | IReq_ControllerSessionGet | IReq_ControllerSessionAuxiliaryGet | IReq_ControllerSessionModelUpdate | IReq_ControllerSessionScratchpadSave | IReq_ControllerSessionIntelligenceAsk | IReq_ControllerSessionMessagesPage | IReq_ControllerSessionMessageGet | IReq_ControllerSessionCreate | IReq_ControllerSessionDelete | IReq_ControllerSessionDiscardEmpty | IReq_ControllerSessionDraftGet | IReq_ControllerSessionDraftUpdate | IReq_ControllerSessionSend | IReq_ControllerSessionAbort | IReq_ControllerPermissionReply | IReq_ControllerQuestionReply | IReq_ControllerSessionRename | IReq_ControllerSessionArchive | IReq_ControllerSessionGroupsGet | IReq_ControllerSessionGroupsUpdate | IReq_ControllerSessionYolo | IReq_ControllerResourceList | IReq_ControllerResourceCreate | IReq_ControllerResourceRename | IReq_ControllerResourceAttach | IReq_ControllerResourceDetach | IReq_ControllerResourceRetire | IReq_ControllerResourceStart | IReq_ControllerResourceStop | IReq_ControllerBrowserViewOpen | IReq_ControllerBrowserViewActivate | IReq_ControllerBrowserViewRecover | IReq_ControllerBrowserViewClose | IReq_ControllerTerminalList | IReq_ControllerTerminalCreate | IReq_ControllerTerminalRename | IReq_ControllerTerminalRemove | IReq_ControllerTerminalAttach | IReq_ControllerTerminalDetach | IReq_ControllerTerminalInput | IReq_ControllerTerminalResize | IReq_ControllerTerminalOutput | IReq_ControllerEvent;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agl",
3
- "version": "22.0.4",
3
+ "version": "24.0.0",
4
4
  "controllerUpgradeManagementVersion": 2,
5
5
  "private": false,
6
6
  "description": "Agent Gateway Layer for OpenCode and FlexHarness sessions",
@@ -19,16 +19,16 @@
19
19
  "@api.global/typedrequest": "8.0.2",
20
20
  "@api.global/typedrequest-interfaces": "7.1.0",
21
21
  "@api.global/typedserver": "11.1.0",
22
- "@api.global/typedsocket": "8.0.0",
23
- "@design.estate/dees-catalog": "6.10.2",
22
+ "@api.global/typedsocket": "8.0.1",
23
+ "@design.estate/dees-catalog": "6.12.1",
24
24
  "@design.estate/dees-element": "2.4.0",
25
- "@modelprofile.com/browser-runtime": "3.0.1",
25
+ "@modelprofile.com/browser-runtime": "3.1.1",
26
26
  "@modelprofile.com/crossharness-mcp": "4.1.1",
27
- "@modelprofile.com/flexharness": "4.1.2",
27
+ "@modelprofile.com/flexharness": "5.0.0",
28
28
  "@opencode-ai/sdk": "1.18.15",
29
29
  "@push.rocks/smartagent": "5.0.1",
30
30
  "@push.rocks/smartai": "6.0.0",
31
- "@push.rocks/smartbrowser": "4.0.0",
31
+ "@push.rocks/smartbrowser": "4.0.1",
32
32
  "@push.rocks/smartcli": "4.3.0",
33
33
  "@push.rocks/smartdata": "11.6.1",
34
34
  "@push.rocks/smartdb": "5.2.1",
@@ -61,7 +61,7 @@
61
61
  },
62
62
  "devDependencies": {
63
63
  "@git.zone/tsbuild": "4.4.2",
64
- "@git.zone/tsbundle": "2.11.4",
64
+ "@git.zone/tsbundle": "2.13.0",
65
65
  "@git.zone/tsrun": "2.0.6",
66
66
  "@git.zone/tstest": "4.0.0",
67
67
  "@types/node": "26.2.0"
package/readme.md CHANGED
@@ -43,6 +43,12 @@ OpenCode and FlexHarness are supervised independently. Flex can restart without
43
43
 
44
44
  The browser receives normalized AGL data. It never receives the OpenCode server password, provider credentials, private database descriptors, raw provider responses, or Flex private snapshots.
45
45
 
46
+ ### Live Transcript Delivery
47
+
48
+ Controller protocol v24 sends bounded live Assistant text and reasoning deltas when the browser already owns the exact preceding transcript revision. Every delta carries its stream epoch, revision, and UTF-8 coordinates; Flex deltas also carry the harness's authoritative transcript order. The browser applies only contiguous, correctly sized updates to the canonical transcript; a gap, stale owner, invalid coordinate, or queue overflow blocks further deltas from that epoch and requests authoritative session-detail hydration instead. Only adjacent compatible pending deltas may be coalesced, so interleaved updates retain their original order.
49
+
50
+ Streaming text is rendered without Markdown parsing. AGL refreshes the affected messages and enables normal Markdown rendering after the harness reports terminal state or authoritative hydration settles the transcript. This keeps long responses responsive without creating a second browser-side message graph.
51
+
46
52
  ## Requirements
47
53
 
48
54
  - Node.js 24 or newer.
@@ -201,7 +207,11 @@ AGL allows at most eight running terminals per project and 32 controller-wide.
201
207
 
202
208
  ### Browsers
203
209
 
204
- A browser resource provides tabs, navigation, viewport control, mouse, keyboard, and text input through a human canvas. Frames use finite authenticated binary streams rather than public URLs or base64 JSON payloads.
210
+ A browser resource provides tabs, navigation, viewport control, mouse, keyboard, and text input through a human canvas. Protocol v24 opens one authenticated persistent event stream and one paired operation stream for each human view. Every pair is bound to the exact peer, credential, resource authority, attachment revision, view, and stream generation.
211
+
212
+ State and operation results use bounded JSON packets. A frame is sent as one validated metadata packet immediately followed by its raw image bytes, rather than through a public URL or base64 JSON payload. Operation IDs, pending bytes, acknowledgements, event delivery, input rates, and recovery attempts are all bounded. Only adjacent compatible pointer-move or viewport operations can be coalesced, while cancellation retains a separately fenced path to live work.
213
+
214
+ The browser installs its renderer before activating a view. A recoverable stream failure suspends input, retires the old pair, opens and starts the next stream generation, and resumes the renderer's listeners before activating the replacement. Activation refreshes the runtime frame boundary, and input resumes only after that boundary arrives. Stale activation, recovery, cancellation, and close messages cannot act on another generation.
205
215
 
206
216
  When attached to a Flex conversation, the resource can provide permission-gated `navigate`, `snapshot`, `screenshot`, `click`, `fill`, and `press` actions to that exact run. Every channel is bound to the project, resource revision, session, run, actor, and current Flex generation.
207
217
 
@@ -317,7 +327,7 @@ Do not move these directories or edit migration and upgrade journals by hand.
317
327
 
318
328
  SmartData stores runtime configuration, passkey metadata, projects, layouts, model choices, scratchpads, tasks, goals, resources, Flex public projections, provider metadata, and bounded audit events. Prompt text is not written to audit records.
319
329
 
320
- Terminal I/O, active browser views, frame streams, composer drafts and their pending attachment state, active capability leases, and running processes remain memory-only. Once a prompt is submitted, attachment files exist only in private operation directories for the lifetime of that exact harness operation.
330
+ Terminal I/O, active browser views and their paired transport streams, composer drafts and their pending attachment state, active capability leases, and running processes remain memory-only. Once a prompt is submitted, attachment files exist only in private operation directories for the lifetime of that exact harness operation.
321
331
 
322
332
  Library consumers can resolve the same home contract:
323
333
 
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: 'agl',
6
- version: '22.0.4',
6
+ version: '24.0.0',
7
7
  description: 'Agent Gateway Layer for OpenCode and FlexHarness sessions'
8
8
  }
@@ -1246,7 +1246,7 @@ export class SmartDataAuthStore implements IAuthStore {
1246
1246
  name: nameArg,
1247
1247
  directory: directoryArg,
1248
1248
  directoryIdentityState: 'bound',
1249
- directoryIdentity: structuredClone(identityArg),
1249
+ directoryIdentity: { ancestry: structuredClone(identityArg.ancestry) },
1250
1250
  createdAt: new Date(),
1251
1251
  };
1252
1252
  const result = await ControllerProjectModel.exact.insert(candidate);
@@ -84,6 +84,7 @@ export interface IControllerBrowserResourceHostOptions {
84
84
  export interface IControllerBrowserHumanView {
85
85
  lease: plugins.browserRuntime.BrowserRuntimeLease;
86
86
  activate(listenerArg: (eventArg: plugins.browserRuntime.TBrowserRuntimeEvent) => void): Promise<void>;
87
+ refreshFrameStream(signalArg: AbortSignal): Promise<void>;
87
88
  close(): Promise<void>;
88
89
  }
89
90
 
@@ -854,6 +855,12 @@ export class ControllerBrowserResourceHost implements IControllerResourceRuntime
854
855
  });
855
856
  return activationPromise;
856
857
  },
858
+ refreshFrameStream: async (signalArg) => {
859
+ if (closing || !subscription || subscriptionClosed) {
860
+ throw new Error('The active browser frame subscription is unavailable.');
861
+ }
862
+ await lease.refreshFrameStream({ signal: signalArg });
863
+ },
857
864
  close: async () => {
858
865
  closing = true;
859
866
  const deadlineAt = Date.now() + this.cleanupTimeoutMs;