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.
- package/changelog.md +21 -0
- package/dist_serve/bundle.js +2418 -2408
- package/dist_serve/bundle.js.map +1 -0
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/classes.authstore.js +2 -2
- package/dist_ts/classes.browserresourcehost.d.ts +1 -0
- package/dist_ts/classes.browserresourcehost.js +7 -1
- package/dist_ts/classes.controller.d.ts +37 -5
- package/dist_ts/classes.controller.js +1491 -249
- package/dist_ts/classes.flexservice.d.ts +5 -0
- package/dist_ts/classes.flexservice.js +131 -4
- package/dist_ts/classes.opencodeclient.d.ts +2 -0
- package/dist_ts/classes.opencodeclient.js +23 -1
- package/dist_ts/classes.validation.d.ts +9 -1
- package/dist_ts/classes.validation.js +62 -7
- package/dist_ts/interfaces.flexipc.d.ts +18 -1
- package/dist_ts/interfaces.flexipc.js +42 -8
- package/dist_ts_interfaces/browsertransport.d.ts +72 -0
- package/dist_ts_interfaces/browsertransport.js +47 -0
- package/dist_ts_interfaces/index.d.ts +1 -0
- package/dist_ts_interfaces/index.js +2 -1
- package/dist_ts_interfaces/interfaces.d.ts +42 -7
- package/dist_ts_interfaces/interfaces.js +5 -3
- package/dist_ts_interfaces/requests.d.ts +20 -21
- package/package.json +7 -7
- package/readme.md +12 -2
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/classes.authstore.ts +1 -1
- package/ts/classes.browserresourcehost.ts +7 -0
- package/ts/classes.controller.ts +1960 -305
- package/ts/classes.flexservice.ts +132 -2
- package/ts/classes.opencodeclient.ts +19 -0
- package/ts/classes.validation.ts +77 -6
- package/ts/interfaces.flexipc.ts +65 -7
- package/ts_interfaces/browsertransport.ts +126 -0
- package/ts_interfaces/index.ts +1 -0
- package/ts_interfaces/interfaces.ts +46 -11
- package/ts_interfaces/requests.ts +23 -30
- package/ts_web/00_commitinfo_data.ts +1 -1
- package/ts_web/classes.browserviewtransport.ts +532 -0
- package/ts_web/classes.controllersocketclient.ts +119 -29
- package/ts_web/elements.harnesscontrollerapp.ts +1727 -287
- package/ts_web/index.ts +1 -0
- 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,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,
|
|
4
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90c19pbnRlcmZhY2VzL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGNBQWMsaUJBQWlCLENBQUM7QUFDaEMsY0FBYyx1QkFBdUIsQ0FBQztBQUN0QyxjQUFjLGVBQWUsQ0FBQyJ9
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
|
|
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
|
|
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
|
-
|
|
225
|
+
dataByteLength: number;
|
|
226
|
+
}
|
|
227
|
+
export interface IControllerBrowserFrame extends Omit<IControllerBrowserFrameMetadata, 'dataByteLength'> {
|
|
228
|
+
data: Uint8Array;
|
|
224
229
|
}
|
|
225
|
-
export type TControllerBrowserViewEvent
|
|
230
|
+
export type TControllerBrowserViewEvent = {
|
|
226
231
|
type: 'state';
|
|
227
232
|
state: IControllerBrowserViewState;
|
|
228
233
|
} | {
|
|
229
234
|
type: 'frame';
|
|
230
|
-
frame: IControllerBrowserFrame
|
|
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
|
-
|
|
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,
|
|
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,
|
|
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
|
|
679
|
-
method: 'controller.browser.view.
|
|
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
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
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
|
-
|
|
699
|
-
|
|
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
|
-
|
|
704
|
-
|
|
705
|
-
|
|
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 |
|
|
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": "
|
|
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.
|
|
23
|
-
"@design.estate/dees-catalog": "6.
|
|
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.
|
|
25
|
+
"@modelprofile.com/browser-runtime": "3.1.1",
|
|
26
26
|
"@modelprofile.com/crossharness-mcp": "4.1.1",
|
|
27
|
-
"@modelprofile.com/flexharness": "
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
|
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
|
|
package/ts/00_commitinfo_data.ts
CHANGED
package/ts/classes.authstore.ts
CHANGED
|
@@ -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;
|