@opengeni/runtime 3.2.2 → 3.4.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 (69) hide show
  1. package/dist/agent-LJT5NPWT.js +9 -0
  2. package/dist/assets/codemode-client.json +1 -1
  3. package/dist/browser-current-tab.d.ts +46 -0
  4. package/dist/browser-model-text.d.ts +126 -0
  5. package/dist/{chunk-2AUDDDO2.js → chunk-3DFH3ZHU.js} +784 -121
  6. package/dist/chunk-3DFH3ZHU.js.map +1 -0
  7. package/dist/{chunk-HJSIPTFA.js → chunk-4XDJ4TJA.js} +2 -2
  8. package/dist/{chunk-XQ23VCZ4.js → chunk-6FQ6KEII.js} +3 -3
  9. package/dist/{chunk-7LJ7KDPI.js → chunk-ERD4ICVB.js} +4 -3
  10. package/dist/{chunk-462CH77G.js → chunk-ETTCGPBT.js} +400 -9
  11. package/dist/chunk-ETTCGPBT.js.map +1 -0
  12. package/dist/{chunk-7OUG7WBV.js → chunk-GWRBALGQ.js} +181 -13
  13. package/dist/chunk-GWRBALGQ.js.map +1 -0
  14. package/dist/{chunk-YG26XE7B.js → chunk-JYDG2A7H.js} +2 -2
  15. package/dist/{chunk-RSHQSLEJ.js → chunk-KIL4FGX5.js} +3 -3
  16. package/dist/{chunk-NWS4HPB7.js → chunk-MIAL5I4O.js} +2 -2
  17. package/dist/{chunk-Z5U6WE22.js → chunk-PRZPGRIK.js} +2 -2
  18. package/dist/{chunk-KCPW4K7L.js → chunk-PZQUUBEB.js} +2 -2
  19. package/dist/{chunk-5WJOPANS.js → chunk-Y5THZH5N.js} +7 -7
  20. package/dist/codex-tool-search.d.ts +9 -0
  21. package/dist/gmail-rest-mcp.js +8 -8
  22. package/dist/index.d.ts +3 -0
  23. package/dist/index.js +14 -12
  24. package/dist/interaction-tool-json-schema.d.ts +27 -0
  25. package/dist/{lazy-manifest-AJ6XPJ4F.js → lazy-manifest-BLZ3UZLX.js} +4 -4
  26. package/dist/lazy-tool-transport.d.ts +10 -0
  27. package/dist/{localSources-SSIEH5F5.js → localSources-I6SIQ6CX.js} +6 -6
  28. package/dist/model-call.js +3 -3
  29. package/dist/sandbox/browser-control-client.d.ts +87 -0
  30. package/dist/sandbox/browser-control-http.d.ts +33 -0
  31. package/dist/sandbox/index.d.ts +1 -1
  32. package/dist/sandbox/index.js +7 -7
  33. package/dist/sandbox/routing/backend-resolver.d.ts +1 -0
  34. package/dist/sandbox/selfhosted/session.d.ts +22 -0
  35. package/dist/slack-rest-mcp.js +8 -8
  36. package/dist/workspace-tool-gateway.js +12 -12
  37. package/package.json +14 -14
  38. package/src/browser-current-tab.ts +139 -0
  39. package/src/browser-model-text.ts +378 -0
  40. package/src/bundled_site_skills/opengeni-sites/SKILL.md +46 -12
  41. package/src/codex-tool-search.ts +53 -0
  42. package/src/index.ts +39 -1
  43. package/src/interaction-tool-json-schema.ts +281 -0
  44. package/src/interaction-tools.ts +425 -235
  45. package/src/lazy-tool-transport.ts +229 -10
  46. package/src/model-input.ts +12 -1
  47. package/src/sandbox/browser-control-client.ts +425 -0
  48. package/src/sandbox/browser-control-http.ts +32 -0
  49. package/src/sandbox/index.ts +4 -0
  50. package/src/sandbox/routing/backend-resolver.ts +2 -0
  51. package/src/sandbox/selfhosted/session.ts +154 -0
  52. package/dist/agent-CTPLA3HP.js +0 -9
  53. package/dist/browser-action-json-schema.d.ts +0 -4
  54. package/dist/chunk-2AUDDDO2.js.map +0 -1
  55. package/dist/chunk-462CH77G.js.map +0 -1
  56. package/dist/chunk-7OUG7WBV.js.map +0 -1
  57. package/src/browser-action-json-schema.ts +0 -10
  58. /package/dist/{agent-CTPLA3HP.js.map → agent-LJT5NPWT.js.map} +0 -0
  59. /package/dist/{chunk-HJSIPTFA.js.map → chunk-4XDJ4TJA.js.map} +0 -0
  60. /package/dist/{chunk-XQ23VCZ4.js.map → chunk-6FQ6KEII.js.map} +0 -0
  61. /package/dist/{chunk-7LJ7KDPI.js.map → chunk-ERD4ICVB.js.map} +0 -0
  62. /package/dist/{chunk-YG26XE7B.js.map → chunk-JYDG2A7H.js.map} +0 -0
  63. /package/dist/{chunk-RSHQSLEJ.js.map → chunk-KIL4FGX5.js.map} +0 -0
  64. /package/dist/{chunk-NWS4HPB7.js.map → chunk-MIAL5I4O.js.map} +0 -0
  65. /package/dist/{chunk-Z5U6WE22.js.map → chunk-PRZPGRIK.js.map} +0 -0
  66. /package/dist/{chunk-KCPW4K7L.js.map → chunk-PZQUUBEB.js.map} +0 -0
  67. /package/dist/{chunk-5WJOPANS.js.map → chunk-Y5THZH5N.js.map} +0 -0
  68. /package/dist/{lazy-manifest-AJ6XPJ4F.js.map → lazy-manifest-BLZ3UZLX.js.map} +0 -0
  69. /package/dist/{localSources-SSIEH5F5.js.map → localSources-I6SIQ6CX.js.map} +0 -0
@@ -18,7 +18,7 @@ import {
18
18
  shellQuote,
19
19
  tool,
20
20
  withSandboxSpan
21
- } from "./chunk-7LJ7KDPI.js";
21
+ } from "./chunk-ERD4ICVB.js";
22
22
 
23
23
  // ../../node_modules/.bun/@openai+agents-core@0.14.3+933c5e7db4cd33c2/node_modules/@openai/agents-core/dist/sandbox/capabilities/transport.mjs
24
24
  function supportsResponsesCompactionTransport(modelInstance) {
@@ -999,4 +999,4 @@ export {
999
999
  probeSandboxPathExists,
1000
1000
  SandboxAgent
1001
1001
  };
1002
- //# sourceMappingURL=chunk-HJSIPTFA.js.map
1002
+ //# sourceMappingURL=chunk-4XDJ4TJA.js.map
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  connectorAttachmentFileName
3
- } from "./chunk-Z5U6WE22.js";
3
+ } from "./chunk-PRZPGRIK.js";
4
4
  import {
5
5
  isRoutingMutationOutcomeUnknownError
6
- } from "./chunk-5WJOPANS.js";
6
+ } from "./chunk-Y5THZH5N.js";
7
7
 
8
8
  // src/gmail-rest-mcp.ts
9
9
  import {
@@ -2258,4 +2258,4 @@ export {
2258
2258
  gmailRestToolIsMutation,
2259
2259
  gmailRestResultOutcome
2260
2260
  };
2261
- //# sourceMappingURL=chunk-XQ23VCZ4.js.map
2261
+ //# sourceMappingURL=chunk-6FQ6KEII.js.map
@@ -27556,7 +27556,7 @@ var SandboxMemoryGenerationManager = class {
27556
27556
  if (!transcript) {
27557
27557
  throw new UserError(`Memory rollout transcript was not found: ${transcriptPath}`);
27558
27558
  }
27559
- const { SandboxAgent } = await import("./agent-CTPLA3HP.js");
27559
+ const { SandboxAgent } = await import("./agent-LJT5NPWT.js");
27560
27560
  const phaseOneAgent = new SandboxAgent({
27561
27561
  name: "sandbox-memory-phase-one",
27562
27562
  instructions: renderRolloutExtractionInstructions(generate.extraPrompt),
@@ -27617,7 +27617,7 @@ var SandboxMemoryGenerationManager = class {
27617
27617
  })) {
27618
27618
  return;
27619
27619
  }
27620
- const { SandboxAgent } = await import("./agent-CTPLA3HP.js");
27620
+ const { SandboxAgent } = await import("./agent-LJT5NPWT.js");
27621
27621
  const phaseTwoAgent = new SandboxAgent({
27622
27622
  name: "sandbox-memory-phase-two",
27623
27623
  model: generate.phaseTwoModel,
@@ -43273,6 +43273,7 @@ export {
43273
43273
  setTraceProcessors,
43274
43274
  setTracingDisabled,
43275
43275
  normalizeHostedMcpRequireApproval,
43276
+ defineToolInputGuardrail,
43276
43277
  ToolGuardrailFunctionOutputFactory,
43277
43278
  applyPatchTool,
43278
43279
  attachClientToolSearchExecutor,
@@ -43358,4 +43359,4 @@ export {
43358
43359
  Runner,
43359
43360
  Agent
43360
43361
  };
43361
- //# sourceMappingURL=chunk-7LJ7KDPI.js.map
43362
+ //# sourceMappingURL=chunk-ERD4ICVB.js.map
@@ -107,7 +107,7 @@ import {
107
107
  withNativeSynchronousCommandCollection,
108
108
  withProviderError,
109
109
  withSandboxProviderCapture
110
- } from "./chunk-5WJOPANS.js";
110
+ } from "./chunk-Y5THZH5N.js";
111
111
  import {
112
112
  applyLocalSourceManifestEntryToState,
113
113
  applyLocalSourceManifestToState,
@@ -122,13 +122,13 @@ import {
122
122
  truncateOutput,
123
123
  validateCredentialPair,
124
124
  validateRemoteSandboxPathForManifest
125
- } from "./chunk-YG26XE7B.js";
125
+ } from "./chunk-JYDG2A7H.js";
126
126
  import {
127
127
  NoopSnapshotSpec,
128
128
  normalizeSandboxClientCreateArgs,
129
129
  resolveSandboxArchiveLimits,
130
130
  validateSandboxArchiveLimits
131
- } from "./chunk-NWS4HPB7.js";
131
+ } from "./chunk-MIAL5I4O.js";
132
132
  import {
133
133
  Manifest,
134
134
  Permissions,
@@ -160,7 +160,7 @@ import {
160
160
  serializeRuntimeEnvironmentForPersistence,
161
161
  shellQuote,
162
162
  withSandboxSpan
163
- } from "./chunk-7LJ7KDPI.js";
163
+ } from "./chunk-ERD4ICVB.js";
164
164
 
165
165
  // src/sandbox/index.ts
166
166
  import { collectSandboxEnvironment, parseExposedPorts } from "@opengeni/config";
@@ -9697,6 +9697,9 @@ async function transferEditorFile(input) {
9697
9697
  return { recovered: false };
9698
9698
  }
9699
9699
 
9700
+ // src/sandbox/browser-control-http.ts
9701
+ var BROWSER_CONTROL_HTTP_REPLY_GRACE_MS = 5e3;
9702
+
9700
9703
  // src/sandbox/selfhosted/retry-policy.ts
9701
9704
  var SELFHOSTED_IDEMPOTENT_READONLY_OPS = /* @__PURE__ */ new Set([
9702
9705
  "ping",
@@ -10920,6 +10923,7 @@ var SelfhostedSession = class {
10920
10923
  resourcePolicySupported;
10921
10924
  operationCpuQuotaSupported;
10922
10925
  transactionalFsWriteSupported;
10926
+ browserControlHttpSupported;
10923
10927
  defaultOpStream;
10924
10928
  connectionInstanceId;
10925
10929
  resolveOperationAdmission;
@@ -10980,6 +10984,7 @@ var SelfhostedSession = class {
10980
10984
  this.resourcePolicySupported = deps.operationResourcePolicySupported === true;
10981
10985
  this.operationCpuQuotaSupported = deps.operationCpuQuotaSupported === true;
10982
10986
  this.transactionalFsWriteSupported = deps.transactionalFsWriteSupported === true;
10987
+ this.browserControlHttpSupported = deps.browserControlHttpSupported === true;
10983
10988
  this.defaultOpStream = deps.opStream;
10984
10989
  this.connectionInstanceId = deps.connectionInstanceId;
10985
10990
  this.resolveOperationAdmission = deps.resolveOperationAdmission;
@@ -10992,7 +10997,8 @@ var SelfhostedSession = class {
10992
10997
  subject: this.subject,
10993
10998
  resourcePolicy: this.resourcePolicy,
10994
10999
  opStream: deps.opStream,
10995
- transactionalFsWriteSupported: this.transactionalFsWriteSupported
11000
+ transactionalFsWriteSupported: this.transactionalFsWriteSupported,
11001
+ browserControlHttpSupported: this.browserControlHttpSupported
10996
11002
  }) : void 0;
10997
11003
  this.state = {
10998
11004
  agentId: deps.agentId,
@@ -11053,7 +11059,8 @@ var SelfhostedSession = class {
11053
11059
  subject: this.subject,
11054
11060
  resourcePolicy: commandPolicy ? this.resourcePolicy : void 0,
11055
11061
  opStream: this.defaultOpStream,
11056
- transactionalFsWriteSupported: this.transactionalFsWriteSupported
11062
+ transactionalFsWriteSupported: this.transactionalFsWriteSupported,
11063
+ browserControlHttpSupported: this.browserControlHttpSupported
11057
11064
  };
11058
11065
  }
11059
11066
  const resolved = await this.resolveOperationAdmission();
@@ -11087,7 +11094,8 @@ var SelfhostedSession = class {
11087
11094
  ),
11088
11095
  resourcePolicy: commandPolicy ? resourcePolicy : void 0,
11089
11096
  opStream: resolved.opStream,
11090
- transactionalFsWriteSupported: resolved.transactionalFsWriteSupported === true
11097
+ transactionalFsWriteSupported: resolved.transactionalFsWriteSupported === true,
11098
+ browserControlHttpSupported: resolved.browserControlHttpSupported === true
11091
11099
  };
11092
11100
  }
11093
11101
  async admitCommand() {
@@ -11564,6 +11572,23 @@ var SelfhostedSession = class {
11564
11572
  reason: null,
11565
11573
  retryable: false
11566
11574
  });
11575
+ if (!terminalProof && !adoptedCommandId && !controlError.neverSent && machineStoppedAnswering(controlError) && this.adoptBackgroundCommand) {
11576
+ try {
11577
+ notifyDurableOpOwnershipTransferStarted(opId);
11578
+ const abandoned = await this.adoptBackgroundCommand({
11579
+ controlWorkspaceId: admission.controlWorkspaceId,
11580
+ enrollmentId: this.agentId,
11581
+ connectionInstanceId: admission.connectionInstanceId,
11582
+ opId,
11583
+ command,
11584
+ abandoned: true
11585
+ });
11586
+ adoptedCommandId = abandoned.commandId;
11587
+ notifyDurableOpOwnershipTransferred(opId);
11588
+ } catch {
11589
+ notifyDurableOpOwnershipTransferFailed(opId);
11590
+ }
11591
+ }
11567
11592
  this.emitOp({
11568
11593
  op: "exec",
11569
11594
  outcome: "failed",
@@ -12078,6 +12103,90 @@ var SelfhostedSession = class {
12078
12103
  }
12079
12104
  return result.browserControlEnsure;
12080
12105
  }
12106
+ /** Send one request to the agent-owned controller of an exact authority
12107
+ * scope, served inside the runner over loopback without starting a process.
12108
+ * `unsupported` means this connection's runner does not serve it and nothing
12109
+ * was sent. `controller_absent` means no controller for that scope and
12110
+ * generation accepted the request, so it was not delivered and the caller may
12111
+ * ensure the controller and send again. A body too large for one reply is
12112
+ * drained from the runner's spool; the request is never repeated. */
12113
+ async browserControlHttp(request) {
12114
+ const admission = await this.admitOperation(false);
12115
+ if (!admission.browserControlHttpSupported) return { kind: "unsupported" };
12116
+ const rpcTimeoutMs = request.timeoutMs + BROWSER_CONTROL_HTTP_REPLY_GRACE_MS;
12117
+ let result;
12118
+ try {
12119
+ result = await this.call(
12120
+ {
12121
+ $case: "browserControlHttp",
12122
+ browserControlHttp: {
12123
+ scopeId: request.scopeId,
12124
+ scopeGeneration: request.scopeGeneration,
12125
+ method: request.method,
12126
+ path: request.path,
12127
+ bearerToken: request.bearerToken,
12128
+ body: request.body ?? new Uint8Array(),
12129
+ hasBody: request.body !== void 0,
12130
+ timeoutMs: request.timeoutMs,
12131
+ maxResponseBytes: String(request.maxResponseBytes)
12132
+ }
12133
+ },
12134
+ rpcTimeoutMs,
12135
+ admission
12136
+ );
12137
+ } catch (error) {
12138
+ if (error instanceof SelfhostedControlError && error.code === ErrorCode2.ERROR_CODE_NOT_FOUND) {
12139
+ return { kind: "controller_absent" };
12140
+ }
12141
+ throw error;
12142
+ }
12143
+ if (result.$case !== "browserControlHttp") {
12144
+ throw new Error(`selfhosted browserControlHttp: unexpected result ${result.$case}`);
12145
+ }
12146
+ const response = result.browserControlHttp;
12147
+ const totalBytes = Number(response.totalBytes);
12148
+ if (!Number.isSafeInteger(totalBytes) || totalBytes < response.body.byteLength || totalBytes > request.maxResponseBytes) {
12149
+ throw new Error("selfhosted browserControlHttp: response length is invalid");
12150
+ }
12151
+ let body = response.body;
12152
+ if (response.spoolId) {
12153
+ const complete = new Uint8Array(totalBytes);
12154
+ complete.set(response.body, 0);
12155
+ let offset = response.body.byteLength;
12156
+ for (; ; ) {
12157
+ const read = await this.call(
12158
+ {
12159
+ $case: "browserControlHttpRead",
12160
+ browserControlHttpRead: { spoolId: response.spoolId, offset: String(offset) }
12161
+ },
12162
+ this.timeoutMs,
12163
+ admission
12164
+ );
12165
+ if (read.$case !== "browserControlHttpRead") {
12166
+ throw new Error(`selfhosted browserControlHttpRead: unexpected result ${read.$case}`);
12167
+ }
12168
+ const part = read.browserControlHttpRead;
12169
+ if (offset + part.data.byteLength > totalBytes) {
12170
+ throw new Error("selfhosted browserControlHttpRead: response exceeds its length");
12171
+ }
12172
+ complete.set(part.data, offset);
12173
+ offset += part.data.byteLength;
12174
+ if (part.done) break;
12175
+ if (part.data.byteLength === 0) {
12176
+ throw new Error("selfhosted browserControlHttpRead: spool made no progress");
12177
+ }
12178
+ }
12179
+ if (offset !== totalBytes) {
12180
+ throw new Error("selfhosted browserControlHttpRead: response is incomplete");
12181
+ }
12182
+ body = complete;
12183
+ } else if (response.body.byteLength !== totalBytes) {
12184
+ throw new Error("selfhosted browserControlHttp: response is incomplete");
12185
+ }
12186
+ const headers = /* @__PURE__ */ new Map();
12187
+ for (const header of response.headers) headers.set(header.name.toLowerCase(), header.value);
12188
+ return { kind: "response", status: response.status, headers, body };
12189
+ }
12081
12190
  /** Open one browser-native frame producer and return its canonical relay
12082
12191
  * endpoint. This does not route through `resolveExposedPort`: that legacy
12083
12192
  * method allocates PTY/desktop resources based on fixed ports, while this op
@@ -12222,6 +12331,7 @@ var SelfhostedSandboxClient = class {
12222
12331
  operationResourcePolicySupported;
12223
12332
  operationCpuQuotaSupported;
12224
12333
  transactionalFsWriteSupported;
12334
+ browserControlHttpSupported;
12225
12335
  resolveOperationAdmission;
12226
12336
  adoptBackgroundCommand;
12227
12337
  settleBackgroundCommand;
@@ -12245,6 +12355,7 @@ var SelfhostedSandboxClient = class {
12245
12355
  this.operationResourcePolicySupported = opts.operationResourcePolicySupported;
12246
12356
  this.operationCpuQuotaSupported = opts.operationCpuQuotaSupported;
12247
12357
  this.transactionalFsWriteSupported = opts.transactionalFsWriteSupported;
12358
+ this.browserControlHttpSupported = opts.browserControlHttpSupported;
12248
12359
  this.resolveOperationAdmission = opts.resolveOperationAdmission;
12249
12360
  this.adoptBackgroundCommand = opts.adoptBackgroundCommand;
12250
12361
  this.settleBackgroundCommand = opts.settleBackgroundCommand;
@@ -12279,6 +12390,7 @@ var SelfhostedSandboxClient = class {
12279
12390
  } : {},
12280
12391
  ...this.operationCpuQuotaSupported !== void 0 ? { operationCpuQuotaSupported: this.operationCpuQuotaSupported } : {},
12281
12392
  transactionalFsWriteSupported: this.transactionalFsWriteSupported === true,
12393
+ browserControlHttpSupported: this.browserControlHttpSupported === true,
12282
12394
  ...this.resolveOperationAdmission !== void 0 ? { resolveOperationAdmission: this.resolveOperationAdmission } : {},
12283
12395
  ...this.adoptBackgroundCommand !== void 0 ? { adoptBackgroundCommand: this.adoptBackgroundCommand } : {},
12284
12396
  ...this.settleBackgroundCommand !== void 0 ? { settleBackgroundCommand: this.settleBackgroundCommand } : {},
@@ -12350,6 +12462,7 @@ async function buildSelfhostedBackendSession(deps) {
12350
12462
  } : {},
12351
12463
  ...deps.operationCpuQuotaSupported !== void 0 ? { operationCpuQuotaSupported: deps.operationCpuQuotaSupported } : {},
12352
12464
  transactionalFsWriteSupported: deps.transactionalFsWriteSupported === true,
12465
+ browserControlHttpSupported: deps.browserControlHttpSupported === true,
12353
12466
  ...deps.resolveOperationAdmission !== void 0 ? { resolveOperationAdmission: deps.resolveOperationAdmission } : {},
12354
12467
  ...deps.adoptBackgroundCommand !== void 0 ? { adoptBackgroundCommand: deps.adoptBackgroundCommand } : {},
12355
12468
  ...deps.settleBackgroundCommand !== void 0 ? { settleBackgroundCommand: deps.settleBackgroundCommand } : {},
@@ -12444,6 +12557,10 @@ function mediaTypeFromPath(path) {
12444
12557
  if (p.endsWith(".svg") || p.endsWith(".svgz")) return "image/svg+xml";
12445
12558
  return void 0;
12446
12559
  }
12560
+ function machineStoppedAnswering(error) {
12561
+ const faultClass = selfhostedFaultClass(error);
12562
+ return faultClass === "offline" || faultClass === "reconnecting" || faultClass === "draining";
12563
+ }
12447
12564
  function randomNonce() {
12448
12565
  return String(Math.floor(Math.random() * Number.MAX_SAFE_INTEGER));
12449
12566
  }
@@ -14466,6 +14583,28 @@ function placementControllerWorkdir(session) {
14466
14583
  if (!session.ensureBrowserControl) return MANAGED_PLACEMENT_CONTROLLER_WORKDIR;
14467
14584
  return session.controllerHostOs?.() === "windows" ? "." : NATIVE_PLACEMENT_CONTROLLER_WORKDIR;
14468
14585
  }
14586
+ var BROWSER_WORKING_COPY_REFUSALS = [
14587
+ "unsupported_platform",
14588
+ "browser_running",
14589
+ "working_copy_invalid",
14590
+ "receipt_not_adoptable",
14591
+ "authority_changed",
14592
+ "process_state_unknown",
14593
+ "adoption_not_needed",
14594
+ "adoption_unresolved"
14595
+ ];
14596
+ var BROWSER_WORKING_COPY_ADOPTION_PHASES = [
14597
+ "intent",
14598
+ "copied",
14599
+ "receipt",
14600
+ "source_preserved",
14601
+ "adopted",
14602
+ "interrupted",
14603
+ "failed",
14604
+ "collision",
14605
+ "reverting",
14606
+ "reverted"
14607
+ ];
14469
14608
  var BrowserControlTransportError = class extends Error {
14470
14609
  name = "BrowserControlTransportError";
14471
14610
  retryable = true;
@@ -14647,7 +14786,8 @@ var BrowserControlClient = class {
14647
14786
  }
14648
14787
  return {
14649
14788
  ...returnedReference,
14650
- observation: BrowserObservation.parse(data.observation)
14789
+ observation: BrowserObservation.parse(data.observation),
14790
+ ...creationTargets(data.targets, returnedReference)
14651
14791
  };
14652
14792
  }
14653
14793
  async createComputerSession(input) {
@@ -14830,6 +14970,86 @@ var BrowserControlClient = class {
14830
14970
  }
14831
14971
  return receipt;
14832
14972
  }
14973
+ /** Read-only evidence about a preserved working copy whose controller
14974
+ * memory was lost: the exact digest of its bytes and whether it can be
14975
+ * adopted. Hashing a large profile can take minutes. */
14976
+ async inspectWorkingCopy(input) {
14977
+ const reference = parseReference(input);
14978
+ const data = await this.requestJson({
14979
+ method: "POST",
14980
+ path: `/v1/browser-sessions/${reference.browserSessionId}/working-copy/inspection`,
14981
+ token: this.adminToken,
14982
+ body: workingCopyAuthorityBody(reference, input),
14983
+ timeoutMs: BROWSER_STATE_TRANSFER_TIMEOUT_MS
14984
+ });
14985
+ return parseWorkingCopyInspection(data, reference);
14986
+ }
14987
+ /** Adopt the exact inspected bytes of a preserved working copy. A lost reply
14988
+ * is checked with {@link workingCopyAdoption}. Sending the same operation id
14989
+ * again never repeats a side effect: it only settles what that operation
14990
+ * already did, under the authority that approved it. */
14991
+ async adoptWorkingCopy(input) {
14992
+ const reference = parseReference(input);
14993
+ const operationId = requireUuid(input.operationId, "working copy adoption id");
14994
+ const data = await this.requestJson({
14995
+ method: "POST",
14996
+ path: `/v1/browser-sessions/${reference.browserSessionId}/working-copy/adoptions`,
14997
+ token: this.adminToken,
14998
+ body: {
14999
+ ...workingCopyAuthorityBody(reference, input),
15000
+ operationId,
15001
+ manifestDigest: sha2563(input.manifestDigest, "working copy manifest digest")
15002
+ },
15003
+ timeoutMs: BROWSER_STATE_TRANSFER_TIMEOUT_MS
15004
+ });
15005
+ const adoption = parseWorkingCopyAdoption(data, reference, "current");
15006
+ if (adoption.operationId !== operationId) {
15007
+ throw new BrowserControlProtocolError("browser controller returned another adoption");
15008
+ }
15009
+ return adoption;
15010
+ }
15011
+ /** The recorded state of one adoption, read without changing it. */
15012
+ async workingCopyAdoption(reference, operationId) {
15013
+ const binding2 = parseReference(reference);
15014
+ const id = requireUuid(operationId, "working copy adoption id");
15015
+ const data = await this.requestJson({
15016
+ method: "GET",
15017
+ path: `/v1/browser-sessions/${binding2.browserSessionId}/working-copy/adoptions/${id}`,
15018
+ token: this.adminToken
15019
+ });
15020
+ if (!isRecord2(data) || typeof data.inFlight !== "boolean") {
15021
+ throw new BrowserControlProtocolError(
15022
+ "browser controller returned malformed adoption status"
15023
+ );
15024
+ }
15025
+ const adoption = data.adoption === null ? null : parseWorkingCopyAdoption(data.adoption, binding2, "recorded");
15026
+ if (adoption && adoption.operationId !== id) {
15027
+ throw new BrowserControlProtocolError("browser controller returned another adoption");
15028
+ }
15029
+ return { inFlight: data.inFlight, adoption };
15030
+ }
15031
+ /** Revert one unfinished adoption under the browser's current authority:
15032
+ * its own directory goes back to the live path and the staged copy is
15033
+ * kept. Retrying the same revert finishes one that stopped part way. */
15034
+ async revertWorkingCopyAdoption(input) {
15035
+ const reference = parseReference(input);
15036
+ const id = requireUuid(input.operationId, "working copy adoption id");
15037
+ const data = await this.requestJson({
15038
+ method: "POST",
15039
+ path: `/v1/browser-sessions/${reference.browserSessionId}/working-copy/adoptions/${id}/revert`,
15040
+ token: this.adminToken,
15041
+ body: workingCopyAuthorityBody(reference, input),
15042
+ timeoutMs: BROWSER_STATE_TRANSFER_TIMEOUT_MS
15043
+ });
15044
+ if (!isRecord2(data) || typeof data.inFlight !== "boolean") {
15045
+ throw new BrowserControlProtocolError("browser controller returned malformed revert status");
15046
+ }
15047
+ const adoption = data.adoption === null ? null : parseWorkingCopyAdoption(data.adoption, reference, "recorded");
15048
+ if (adoption && adoption.operationId !== id) {
15049
+ throw new BrowserControlProtocolError("browser controller returned another adoption");
15050
+ }
15051
+ return { inFlight: data.inFlight, adoption };
15052
+ }
14833
15053
  sessionClient(input) {
14834
15054
  return new BrowserControlSessionClient(this, input);
14835
15055
  }
@@ -15000,6 +15220,18 @@ var BrowserControlClient = class {
15000
15220
  "signed Channel B requires a host-fetch controller endpoint"
15001
15221
  );
15002
15222
  }
15223
+ const native = await this.requestNative(input, BROWSER_CONTROL_MAX_JSON_BYTES);
15224
+ if (native) {
15225
+ let text;
15226
+ try {
15227
+ text = new TextDecoder("utf-8", { fatal: true }).decode(native.body);
15228
+ } catch (error) {
15229
+ throw new BrowserControlProtocolError("browser controller response is not UTF-8", {
15230
+ cause: error
15231
+ });
15232
+ }
15233
+ return parseEnvelope(text, native.status);
15234
+ }
15003
15235
  if (this.session.execWithInput && (input.body === void 0 || Buffer.byteLength(JSON.stringify(input.body)) <= 32 * 1024)) {
15004
15236
  try {
15005
15237
  const response = await this.requestStream(input, BROWSER_CONTROL_MAX_JSON_BYTES);
@@ -15144,6 +15376,17 @@ var BrowserControlClient = class {
15144
15376
  "signed Channel B requires a host-fetch controller endpoint"
15145
15377
  );
15146
15378
  }
15379
+ const nativeFrame = await this.requestNative(
15380
+ input,
15381
+ input.surface === "browser" ? 24 * 1024 * 1024 : COMPUTER_SCREENSHOT_MAX_BYTES
15382
+ );
15383
+ if (nativeFrame) {
15384
+ if (nativeFrame.status < 200 || nativeFrame.status >= 300) {
15385
+ parseEnvelope(new TextDecoder().decode(nativeFrame.body), nativeFrame.status);
15386
+ throw new BrowserControlProtocolError("browser controller image response is invalid");
15387
+ }
15388
+ return controllerImageFrame(nativeFrame.body, nativeFrame.headers, input);
15389
+ }
15147
15390
  if (this.session.execWithInput) {
15148
15391
  try {
15149
15392
  const response = await this.requestStream(
@@ -15286,8 +15529,61 @@ var BrowserControlClient = class {
15286
15529
  }
15287
15530
  }
15288
15531
  async controllerPort() {
15532
+ if (!this.nativeAuthority || !this.session.ensureBrowserControl) return this.port;
15533
+ return await this.ensureControllerPort(false);
15534
+ }
15535
+ /** The agent-native transport: one in-process loopback request on the
15536
+ * Connected Machine, addressed by authority scope, with no process started.
15537
+ * Null when the placement does not serve it; the caller then keeps its
15538
+ * command transport. A controller that is not running receives nothing, so
15539
+ * it is ensured and the request sent once more whatever its method. */
15540
+ async requestNative(input, maxResponseBytes, retry = true) {
15541
+ const authority = this.nativeAuthority;
15542
+ if (!authority || !this.session.browserControlHttp || !this.session.ensureBrowserControl) {
15543
+ return null;
15544
+ }
15545
+ const method = input.method;
15546
+ if (method !== "GET" && method !== "POST" && method !== "PUT" && method !== "DELETE") {
15547
+ throw new BrowserControlProtocolError("browser controller request method is invalid");
15548
+ }
15549
+ localControllerUrl(this.port, input.path);
15550
+ const body = input.body === void 0 ? void 0 : new TextEncoder().encode(JSON.stringify(input.body));
15551
+ if (body !== void 0 && body.byteLength > BROWSER_CONTROL_MAX_JSON_BYTES) {
15552
+ throw new RangeError("browser controller request body is too large");
15553
+ }
15554
+ let outcome;
15555
+ try {
15556
+ outcome = await this.session.browserControlHttp({
15557
+ scopeId: authority.scopeId,
15558
+ scopeGeneration: authority.scopeGeneration,
15559
+ method,
15560
+ path: input.path,
15561
+ bearerToken: requireToken(input.token, "browser controller token"),
15562
+ ...body === void 0 ? {} : { body },
15563
+ timeoutMs: boundedTimeout2(input.timeoutMs ?? this.timeoutMs),
15564
+ maxResponseBytes
15565
+ });
15566
+ } catch (error) {
15567
+ if (retry && method === "GET") {
15568
+ await this.ensureControllerPort(true);
15569
+ return await this.requestNative(input, maxResponseBytes, false);
15570
+ }
15571
+ throw new BrowserControlTransportError("browser controller request transport failed", {
15572
+ cause: error
15573
+ });
15574
+ }
15575
+ if (outcome.kind === "unsupported") return null;
15576
+ if (outcome.kind === "controller_absent") {
15577
+ if (!retry) throw new BrowserControlTransportError("browser controller is not running");
15578
+ await this.ensureControllerPort(true);
15579
+ return await this.requestNative(input, maxResponseBytes, false);
15580
+ }
15581
+ return outcome;
15582
+ }
15583
+ async ensureControllerPort(replace) {
15289
15584
  if (!this.nativeAuthority || !this.session.ensureBrowserControl) return this.port;
15290
15585
  const key = nativeControllerKey(this.nativeAuthority);
15586
+ if (replace) nativeControllerPorts.delete(key);
15291
15587
  const cached = nativeControllerPorts.get(key);
15292
15588
  if (cached !== void 0) return cached;
15293
15589
  const ensured = await this.session.ensureBrowserControl({
@@ -16119,6 +16415,17 @@ function parseReference(value) {
16119
16415
  controllerGeneration: requireGeneration(value.controllerGeneration)
16120
16416
  };
16121
16417
  }
16418
+ function creationTargets(value, reference) {
16419
+ if (!Array.isArray(value) || value.length > 1e4) return {};
16420
+ const targets = [];
16421
+ for (const entry of value) {
16422
+ const parsed = BrowserTarget.safeParse(entry);
16423
+ if (!parsed.success || parsed.data.browserSessionId !== reference.browserSessionId || parsed.data.controllerGeneration !== reference.controllerGeneration)
16424
+ return {};
16425
+ targets.push(parsed.data);
16426
+ }
16427
+ return { targets };
16428
+ }
16122
16429
  function parseComputerReference(value) {
16123
16430
  if (!isRecord2(value)) {
16124
16431
  throw new BrowserControlProtocolError("computer session binding is invalid");
@@ -16255,6 +16562,81 @@ function boundedProxyUrl(value) {
16255
16562
  }
16256
16563
  return url.toString();
16257
16564
  }
16565
+ function workingCopyAuthorityBody(reference, input) {
16566
+ return {
16567
+ controllerGeneration: reference.controllerGeneration,
16568
+ tokenGeneration: positiveSafeInteger(input.tokenGeneration, "token generation"),
16569
+ controlToken: requireToken(input.controlToken, "control token"),
16570
+ viewToken: requireToken(input.viewToken, "view token")
16571
+ };
16572
+ }
16573
+ function parseWorkingCopyAdoption(value, reference, generation) {
16574
+ if (!isRecord2(value) || value.browserSessionId !== reference.browserSessionId || generation === "current" && value.controllerGeneration !== reference.controllerGeneration || !BROWSER_WORKING_COPY_ADOPTION_PHASES.includes(
16575
+ value.phase
16576
+ ) || !(value.failureCode === null || typeof value.failureCode === "string") || !Array.isArray(value.retainedDirectories) || value.retainedDirectories.length > 64 || !value.retainedDirectories.every(
16577
+ (name) => typeof name === "string" && /^[A-Za-z0-9][A-Za-z0-9._-]{0,255}$/u.test(name)
16578
+ )) {
16579
+ throw new BrowserControlProtocolError("browser controller returned a malformed adoption");
16580
+ }
16581
+ return {
16582
+ browserSessionId: reference.browserSessionId,
16583
+ controllerGeneration: generation === "current" ? reference.controllerGeneration : requireGeneration(value.controllerGeneration),
16584
+ operationId: requireUuid(value.operationId, "working copy adoption id"),
16585
+ manifestDigest: sha2563(value.manifestDigest, "working copy manifest digest"),
16586
+ phase: value.phase,
16587
+ failureCode: value.failureCode === null ? null : requireOpaqueId(value.failureCode, "failure code"),
16588
+ retainedDirectories: value.retainedDirectories,
16589
+ createdAt: timestamp(value.createdAt, "adoption created at"),
16590
+ updatedAt: timestamp(value.updatedAt, "adoption updated at")
16591
+ };
16592
+ }
16593
+ function parseWorkingCopyInspection(value, reference) {
16594
+ if (!isRecord2(value) || value.browserSessionId !== reference.browserSessionId || value.controllerGeneration !== reference.controllerGeneration || typeof value.platformSupported !== "boolean" || typeof value.profileIdentityMatches !== "boolean" || !(value.profileInUse === null || typeof value.profileInUse === "boolean") || !(value.refusal === null || BROWSER_WORKING_COPY_REFUSALS.includes(value.refusal))) {
16595
+ throw new BrowserControlProtocolError("browser controller returned a malformed inspection");
16596
+ }
16597
+ let manifest = null;
16598
+ if (value.manifest !== null) {
16599
+ if (!isRecord2(value.manifest)) {
16600
+ throw new BrowserControlProtocolError("browser controller returned a malformed manifest");
16601
+ }
16602
+ manifest = {
16603
+ digest: sha2563(value.manifest.digest, "working copy manifest digest"),
16604
+ entries: nonnegativeSafeInteger(value.manifest.entries, "working copy entries"),
16605
+ bytes: nonnegativeSafeInteger(value.manifest.bytes, "working copy bytes"),
16606
+ excluded: excludedWorkingCopyEntries(value.manifest.excluded)
16607
+ };
16608
+ }
16609
+ let receipt = null;
16610
+ if (value.receipt !== null) {
16611
+ const raw = value.receipt;
16612
+ if (!isRecord2(raw) || !["launch", "suspend", "retire", "adopt"].includes(raw.intent) || typeof raw.state !== "string" || typeof raw.directoryLaunchAllowed !== "boolean" || typeof raw.authorityMatches !== "boolean" || !(raw.restoreAuthorityDigest === null || typeof raw.restoreAuthorityDigest === "string") || !(raw.adoption === null || isRecord2(raw.adoption))) {
16613
+ throw new BrowserControlProtocolError("browser controller returned a malformed receipt");
16614
+ }
16615
+ receipt = {
16616
+ operationId: requireUuid(raw.operationId, "working runtime receipt id"),
16617
+ intent: raw.intent,
16618
+ state: requireOpaqueId(raw.state, "working runtime receipt state"),
16619
+ directoryLaunchAllowed: raw.directoryLaunchAllowed,
16620
+ authorityMatches: raw.authorityMatches,
16621
+ launchedFromCheckpoint: raw.restoreAuthorityDigest !== null,
16622
+ adoption: isRecord2(raw.adoption) ? {
16623
+ operationId: requireUuid(raw.adoption.operationId, "working copy adoption id"),
16624
+ manifestDigest: sha2563(raw.adoption.manifestDigest, "working copy manifest digest")
16625
+ } : null
16626
+ };
16627
+ }
16628
+ return {
16629
+ browserSessionId: reference.browserSessionId,
16630
+ controllerGeneration: reference.controllerGeneration,
16631
+ platformSupported: value.platformSupported,
16632
+ refusal: value.refusal,
16633
+ manifest,
16634
+ profileIdentityMatches: value.profileIdentityMatches,
16635
+ profileInUse: value.profileInUse,
16636
+ receipt,
16637
+ activeAdoption: value.activeAdoption === null || value.activeAdoption === void 0 ? null : parseWorkingCopyAdoption(value.activeAdoption, reference, "recorded")
16638
+ };
16639
+ }
16258
16640
  function parseStateCaptureReceipt(value) {
16259
16641
  if (!isRecord2(value) || !isRecord2(value.manifest)) {
16260
16642
  throw new BrowserControlProtocolError(
@@ -16850,6 +17232,14 @@ function nonnegativeSafeInteger(value, label) {
16850
17232
  }
16851
17233
  return value;
16852
17234
  }
17235
+ function excludedWorkingCopyEntries(value) {
17236
+ if (!Array.isArray(value) || value.length > 16 || !value.every((entry) => typeof entry === "string" && entry.length > 0 && entry.length <= 256)) {
17237
+ throw new BrowserControlProtocolError(
17238
+ "browser controller returned malformed working copy exclusions"
17239
+ );
17240
+ }
17241
+ return [...value];
17242
+ }
16853
17243
  function parseUnsignedInteger(value, label) {
16854
17244
  const trimmed = value.trim();
16855
17245
  if (!/^(0|[1-9][0-9]*)$/u.test(trimmed)) {
@@ -18876,6 +19266,7 @@ function makeActiveBackendResolver(deps) {
18876
19266
  operationResourcePolicySupported: connection.operationResourcePolicySupported,
18877
19267
  operationCpuQuotaSupported: connection.operationCpuQuotaSupported,
18878
19268
  transactionalFsWriteSupported: connection.transactionalFsWriteSupported === true,
19269
+ browserControlHttpSupported: connection.browserControlHttpSupported === true,
18879
19270
  // The routing proxy caches this session by sandbox+epoch, but command
18880
19271
  // policy and runner authority are mutable. Re-read one coherent DB
18881
19272
  // snapshot only when a new exec/Git is admitted.
@@ -20381,4 +20772,4 @@ export {
20381
20772
  collectSandboxEnvironment2 as collectSandboxEnvironment,
20382
20773
  parseExposedPorts2 as parseExposedPorts
20383
20774
  };
20384
- //# sourceMappingURL=chunk-462CH77G.js.map
20775
+ //# sourceMappingURL=chunk-ETTCGPBT.js.map