@opensteer/runtime-core 0.1.7 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,13 @@
1
+ # @opensteer/runtime-core
2
+
3
+ Shared semantic runtime for Opensteer local and cloud execution.
4
+
5
+ This package is primarily for engine authors and advanced integrations that need
6
+ the lower-level runtime orchestration used by `opensteer`.
7
+
8
+ ```bash
9
+ pnpm add @opensteer/runtime-core
10
+ ```
11
+
12
+ Most users should install [`opensteer`](../opensteer/README.md), which bundles the
13
+ public SDK and CLI on top of this runtime layer.
package/dist/index.cjs CHANGED
@@ -41,7 +41,7 @@ var vm__default = /*#__PURE__*/_interopDefault(vm);
41
41
 
42
42
  // package.json
43
43
  var package_default = {
44
- version: "0.1.7"};
44
+ version: "0.2.0"};
45
45
 
46
46
  // src/version.ts
47
47
  var OPENSTEER_RUNTIME_CORE_VERSION = package_default.version;
@@ -2386,6 +2386,16 @@ var opensteerNetworkQueryOutputSchema = objectSchema(
2386
2386
  required: ["records"]
2387
2387
  }
2388
2388
  );
2389
+ var opensteerNetworkDetailInputSchema = objectSchema(
2390
+ {
2391
+ recordId: stringSchema({ minLength: 1 }),
2392
+ probe: { type: "boolean" }
2393
+ },
2394
+ {
2395
+ title: "OpensteerNetworkDetailInput",
2396
+ required: ["recordId"]
2397
+ }
2398
+ );
2389
2399
  var opensteerParsedCookieSchema = objectSchema(
2390
2400
  {
2391
2401
  name: stringSchema({ minLength: 1 }),
@@ -2491,7 +2501,7 @@ objectSchema(
2491
2501
  }
2492
2502
  );
2493
2503
  var opensteerSessionFetchTransportSchema = enumSchema(
2494
- ["auto", "direct", "matched-tls", "page"],
2504
+ ["auto", "direct", "matched-tls", "context", "page"],
2495
2505
  {
2496
2506
  title: "OpensteerSessionFetchTransport"
2497
2507
  }
@@ -6262,15 +6272,6 @@ var opensteerPageSnapshotOutputSchema = objectSchema(
6262
6272
  required: ["url", "title", "mode", "html", "counters"]
6263
6273
  }
6264
6274
  );
6265
- var opensteerNetworkDetailInputSchema = objectSchema(
6266
- {
6267
- recordId: stringSchema({ minLength: 1 })
6268
- },
6269
- {
6270
- title: "OpensteerNetworkDetailInput",
6271
- required: ["recordId"]
6272
- }
6273
- );
6274
6275
  var opensteerComputerMouseButtonSchema = enumSchema(
6275
6276
  ["left", "middle", "right"],
6276
6277
  {
@@ -6840,6 +6841,7 @@ var opensteerSemanticOperationSpecificationsBase = [
6840
6841
  case "direct":
6841
6842
  return [];
6842
6843
  case "matched-tls":
6844
+ case "context":
6843
6845
  return ["inspect.cookies"];
6844
6846
  case "page":
6845
6847
  return ["pages.manage"];
@@ -7539,7 +7541,6 @@ var DEFAULT_TIMEOUTS = {
7539
7541
  "dom.extract": 15e3,
7540
7542
  "network.query": 15e3,
7541
7543
  "network.detail": 15e3,
7542
- "network.replay": 3e4,
7543
7544
  "scripts.capture": 15e3,
7544
7545
  "session.cookies": 1e4,
7545
7546
  "session.storage": 1e4,
@@ -8361,13 +8362,6 @@ var SqliteSavedNetworkStore = class {
8361
8362
  }
8362
8363
  async save(records, options) {
8363
8364
  const database = await this.requireDatabase();
8364
- const readExisting = database.prepare(`
8365
- SELECT record_id
8366
- FROM saved_network_records
8367
- WHERE session_ref = @session_ref
8368
- AND page_ref_key = @page_ref_key
8369
- AND request_id = @request_id
8370
- `);
8371
8365
  const upsertRecord = database.prepare(buildSavedNetworkUpsertSql(options.bodyWriteMode));
8372
8366
  const insertTag = database.prepare(`
8373
8367
  INSERT OR IGNORE INTO saved_network_tags (record_id, tag)
@@ -8378,14 +8372,8 @@ var SqliteSavedNetworkStore = class {
8378
8372
  for (const entry of records) {
8379
8373
  const url = new URL(entry.record.url);
8380
8374
  const pageRefKey = entry.record.pageRef ?? "";
8381
- const existing = readExisting.get({
8382
- session_ref: entry.record.sessionRef,
8383
- page_ref_key: pageRefKey,
8384
- request_id: entry.record.requestId
8385
- }) ?? void 0;
8386
- const recordId = existing?.record_id ?? entry.recordId;
8387
8375
  upsertRecord.run({
8388
- record_id: recordId,
8376
+ record_id: entry.recordId,
8389
8377
  request_id: entry.record.requestId,
8390
8378
  session_ref: entry.record.sessionRef,
8391
8379
  page_ref: entry.record.pageRef ?? null,
@@ -8430,7 +8418,7 @@ var SqliteSavedNetworkStore = class {
8430
8418
  }
8431
8419
  for (const currentTag of tags) {
8432
8420
  const result = insertTag.run({
8433
- record_id: recordId,
8421
+ record_id: entry.recordId,
8434
8422
  tag: currentTag
8435
8423
  });
8436
8424
  savedCount += result.changes ?? 0;
@@ -8533,6 +8521,49 @@ var SqliteSavedNetworkStore = class {
8533
8521
  return cleared;
8534
8522
  });
8535
8523
  }
8524
+ async *iterateBatches(options = {}) {
8525
+ const database = await this.requireDatabase();
8526
+ const batchSize = Math.max(1, Math.min(options.batchSize ?? 500, 1e3));
8527
+ let cursor;
8528
+ while (true) {
8529
+ const rows = database.prepare(
8530
+ `
8531
+ SELECT
8532
+ r.*,
8533
+ GROUP_CONCAT(t.tag, '${TAG_DELIMITER}') AS tags
8534
+ FROM saved_network_records r
8535
+ LEFT JOIN saved_network_tags t
8536
+ ON t.record_id = r.record_id
8537
+ ${cursor === void 0 ? "" : "WHERE r.saved_at > ? OR (r.saved_at = ? AND r.record_id > ?)"}
8538
+ GROUP BY r.record_id
8539
+ ORDER BY r.saved_at ASC, r.record_id ASC
8540
+ LIMIT ?
8541
+ `
8542
+ ).all(
8543
+ ...cursor === void 0 ? [] : [cursor.savedAt, cursor.savedAt, cursor.recordId],
8544
+ batchSize
8545
+ );
8546
+ if (rows.length === 0) {
8547
+ return;
8548
+ }
8549
+ yield rows.map((row) => inflateSavedNetworkRow(row, options.includeBodies ?? true));
8550
+ const lastRow = rows.at(-1);
8551
+ if (lastRow === void 0) {
8552
+ return;
8553
+ }
8554
+ cursor = {
8555
+ savedAt: lastRow.saved_at,
8556
+ recordId: lastRow.record_id
8557
+ };
8558
+ }
8559
+ }
8560
+ close() {
8561
+ if (this.database !== void 0) {
8562
+ closeSqliteDatabase(this.database);
8563
+ this.database = void 0;
8564
+ this.databaseInitialization = void 0;
8565
+ }
8566
+ }
8536
8567
  async requireDatabase() {
8537
8568
  if (this.database) {
8538
8569
  return this.database;
@@ -8617,15 +8648,6 @@ var SqliteSavedNetworkStore = class {
8617
8648
  saved_at INTEGER NOT NULL
8618
8649
  );
8619
8650
 
8620
- CREATE UNIQUE INDEX IF NOT EXISTS saved_network_records_scope_request
8621
- ON saved_network_records (session_ref, page_ref_key, request_id);
8622
-
8623
- CREATE INDEX IF NOT EXISTS saved_network_records_saved_at
8624
- ON saved_network_records (saved_at DESC);
8625
-
8626
- CREATE INDEX IF NOT EXISTS saved_network_records_capture
8627
- ON saved_network_records (capture);
8628
-
8629
8651
  CREATE TABLE IF NOT EXISTS saved_network_tags (
8630
8652
  record_id TEXT NOT NULL REFERENCES saved_network_records(record_id) ON DELETE CASCADE,
8631
8653
  tag TEXT NOT NULL,
@@ -8635,6 +8657,19 @@ var SqliteSavedNetworkStore = class {
8635
8657
  CREATE INDEX IF NOT EXISTS saved_network_tags_tag
8636
8658
  ON saved_network_tags (tag);
8637
8659
  `);
8660
+ database.exec(`DROP INDEX IF EXISTS saved_network_records_scope_request`);
8661
+ database.exec(`
8662
+ CREATE INDEX IF NOT EXISTS saved_network_records_scope_request
8663
+ ON saved_network_records (session_ref, page_ref_key, request_id)
8664
+ `);
8665
+ database.exec(`
8666
+ CREATE INDEX IF NOT EXISTS saved_network_records_saved_at
8667
+ ON saved_network_records (saved_at DESC)
8668
+ `);
8669
+ database.exec(`
8670
+ CREATE INDEX IF NOT EXISTS saved_network_records_capture
8671
+ ON saved_network_records (capture)
8672
+ `);
8638
8673
  this.ensureColumn(
8639
8674
  database,
8640
8675
  "saved_network_records",
@@ -8954,6 +8989,14 @@ function withSqliteTransaction(database, task) {
8954
8989
  function createSavedNetworkStore(rootPath) {
8955
8990
  return new SqliteSavedNetworkStore(rootPath);
8956
8991
  }
8992
+ async function* iterateSavedNetworkRecordBatches(rootPath, options = {}) {
8993
+ const store = new SqliteSavedNetworkStore(rootPath);
8994
+ try {
8995
+ yield* store.iterateBatches(options);
8996
+ } finally {
8997
+ store.close();
8998
+ }
8999
+ }
8957
9000
  function normalizeContext(context) {
8958
9001
  return {
8959
9002
  ...context?.sessionRef === void 0 ? {} : { sessionRef: context.sessionRef },
@@ -17820,6 +17863,9 @@ var MUTATION_CAPTURE_FINALIZE_TIMEOUT_MS = 5e3;
17820
17863
  var PERSISTED_NETWORK_FLUSH_TIMEOUT_MS = 5e3;
17821
17864
  var PENDING_OPERATION_EVENT_CAPTURE_LIMIT = 64;
17822
17865
  var PENDING_OPERATION_EVENT_CAPTURE_SKEW_MS = 1e3;
17866
+ var REPLAY_PROBE_MIN_ATTEMPT_TIMEOUT_MS = 3e3;
17867
+ var REPLAY_PROBE_MAX_ATTEMPT_TIMEOUT_MS = 15e3;
17868
+ var REPLAY_PROBE_POST_SUCCESS_ATTEMPT_TIMEOUT_MS = 5e3;
17823
17869
  var OpensteerSessionRuntime = class {
17824
17870
  workspace;
17825
17871
  rootPath;
@@ -18681,26 +18727,27 @@ var OpensteerSessionRuntime = class {
18681
18727
  }
18682
18728
  }
18683
18729
  async queryNetwork(input = {}, options = {}) {
18684
- assertValidSemanticOperationInput("network.query", input);
18730
+ const normalizedInput = normalizeNetworkQueryInput(input);
18731
+ assertValidSemanticOperationInput("network.query", normalizedInput);
18685
18732
  const root = await this.ensureRoot();
18686
18733
  const startedAt = Date.now();
18687
18734
  try {
18688
18735
  const output = await this.runWithOperationTimeout(
18689
18736
  "network.query",
18690
18737
  async (timeout) => {
18691
- await this.syncPersistedNetworkSelection(timeout, input, {
18738
+ await this.syncPersistedNetworkSelection(timeout, normalizedInput, {
18692
18739
  includeBodies: false
18693
18740
  });
18694
18741
  const rawRecords = await timeout.runStep(
18695
18742
  () => root.registry.savedNetwork.query({
18696
- ...this.toSavedNetworkQueryInput(input),
18697
- limit: Math.max(input.limit ?? 50, 1e3)
18743
+ ...this.toSavedNetworkQueryInput(normalizedInput),
18744
+ limit: Math.max(normalizedInput.limit ?? 50, 1e3)
18698
18745
  })
18699
18746
  );
18700
- const filtered = filterNetworkSummaryRecords(rawRecords, input);
18747
+ const filtered = filterNetworkSummaryRecords(rawRecords, normalizedInput);
18701
18748
  const sorted = sortPersistedNetworkRecordsChronologically(filtered);
18702
- const sliced = sliceNetworkSummaryWindow(sorted, input);
18703
- const limited = sliced.slice(0, Math.max(1, Math.min(input.limit ?? 50, 200)));
18749
+ const sliced = sliceNetworkSummaryWindow(sorted, normalizedInput);
18750
+ const limited = sliced.slice(0, Math.max(1, Math.min(normalizedInput.limit ?? 50, 200)));
18704
18751
  const summaries = await this.buildNetworkSummaryRecords(limited, timeout);
18705
18752
  return {
18706
18753
  records: summaries
@@ -18714,9 +18761,9 @@ var OpensteerSessionRuntime = class {
18714
18761
  completedAt: Date.now(),
18715
18762
  outcome: "ok",
18716
18763
  data: {
18717
- limit: input.limit ?? 50,
18718
- ...input.capture === void 0 ? {} : { capture: input.capture },
18719
- ...input.json === true ? { json: true } : {},
18764
+ limit: normalizedInput.limit ?? 50,
18765
+ ...normalizedInput.capture === void 0 ? {} : { capture: normalizedInput.capture },
18766
+ ...normalizedInput.json === true ? { json: true } : {},
18720
18767
  count: output.records.length
18721
18768
  },
18722
18769
  context: buildRuntimeTraceContext({
@@ -18741,12 +18788,13 @@ var OpensteerSessionRuntime = class {
18741
18788
  }
18742
18789
  }
18743
18790
  async getNetworkDetail(input, options = {}) {
18791
+ const normalizedRecordId = normalizeNetworkRecordId(input.recordId);
18744
18792
  const startedAt = Date.now();
18745
18793
  try {
18746
18794
  const output = await this.runWithOperationTimeout(
18747
18795
  "network.detail",
18748
18796
  async (timeout) => {
18749
- const record = await this.resolveNetworkRecordByRecordId(input.recordId, timeout, {
18797
+ const record = await this.resolveNetworkRecordByRecordId(normalizedRecordId, timeout, {
18750
18798
  includeBodies: true,
18751
18799
  redactSecretHeaders: false
18752
18800
  });
@@ -18765,8 +18813,8 @@ var OpensteerSessionRuntime = class {
18765
18813
  completedAt: Date.now(),
18766
18814
  outcome: "ok",
18767
18815
  data: {
18768
- recordId: input.recordId,
18769
- status: output.summary.status,
18816
+ recordId: normalizedRecordId,
18817
+ ...output.summary.status === void 0 ? {} : { status: output.summary.status },
18770
18818
  url: output.summary.url
18771
18819
  },
18772
18820
  context: buildRuntimeTraceContext({
@@ -20170,7 +20218,9 @@ var OpensteerSessionRuntime = class {
20170
20218
  ...graphql.persisted === void 0 ? {} : { persisted: graphql.persisted },
20171
20219
  ...graphqlVariables === void 0 ? {} : { variables: graphqlVariables }
20172
20220
  };
20173
- const requestBody = shouldShowRequestBody(record.record.method) && record.record.requestBody !== void 0 ? buildStructuredBodyPreview(record.record.requestBody, record.record.requestHeaders) : void 0;
20221
+ const requestBody = shouldShowRequestBody(record.record.method) && record.record.requestBody !== void 0 ? buildStructuredBodyPreview(record.record.requestBody, record.record.requestHeaders, {
20222
+ truncateData: false
20223
+ }) : void 0;
20174
20224
  const responseBody = record.record.responseBody === void 0 ? void 0 : buildStructuredBodyPreview(record.record.responseBody, record.record.responseHeaders);
20175
20225
  const notes = detectNetworkRecordNotes(record);
20176
20226
  return {
@@ -20200,8 +20250,18 @@ var OpensteerSessionRuntime = class {
20200
20250
  let recommended;
20201
20251
  for (const transport of REPLAY_TRANSPORT_LADDER) {
20202
20252
  const attemptStartedAt = Date.now();
20253
+ const attemptTimeoutMs = resolveReplayProbeAttemptTimeoutMs({
20254
+ remainingMs: timeout.remainingMs(),
20255
+ transportsRemaining: REPLAY_TRANSPORT_LADDER.length - attempts.length,
20256
+ recommendedFound: recommended !== void 0
20257
+ });
20203
20258
  try {
20204
- const output = await this.executeReplayTransportAttempt(transport, request, timeout);
20259
+ const output = await this.executeReplayTransportAttemptWithinBudget(
20260
+ transport,
20261
+ request,
20262
+ timeout,
20263
+ attemptTimeoutMs
20264
+ );
20205
20265
  const ok = matchesSuccessFingerprintFromProtocolResponse(output.response, fingerprint);
20206
20266
  attempts.push({
20207
20267
  transport,
@@ -20217,7 +20277,7 @@ var OpensteerSessionRuntime = class {
20217
20277
  transport,
20218
20278
  ok: false,
20219
20279
  durationMs: Date.now() - attemptStartedAt,
20220
- error: normalizeRuntimeErrorMessage(error)
20280
+ error: normalizeProbeTransportAttemptError(transport, error, attemptTimeoutMs)
20221
20281
  });
20222
20282
  }
20223
20283
  }
@@ -20421,6 +20481,23 @@ var OpensteerSessionRuntime = class {
20421
20481
  }
20422
20482
  }
20423
20483
  }
20484
+ async executeReplayTransportAttemptWithinBudget(transport, request, timeout, attemptTimeoutMs) {
20485
+ if (attemptTimeoutMs === void 0) {
20486
+ return this.executeReplayTransportAttempt(transport, request, timeout);
20487
+ }
20488
+ return runWithPolicyTimeout(
20489
+ {
20490
+ resolveTimeoutMs() {
20491
+ return attemptTimeoutMs;
20492
+ }
20493
+ },
20494
+ {
20495
+ operation: timeout.operation,
20496
+ signal: timeout.signal
20497
+ },
20498
+ (attemptTimeout) => this.executeReplayTransportAttempt(transport, request, attemptTimeout)
20499
+ );
20500
+ }
20424
20501
  async executeFetchTransportAttempt(transport, request, timeout, input) {
20425
20502
  let prepared = finalizeMaterializedTransportRequest(request, transport);
20426
20503
  if (input.cookies !== false && transport === "direct-http" && this.currentBinding() !== void 0) {
@@ -21335,10 +21412,15 @@ var OpensteerSessionRuntime = class {
21335
21412
  return this.observationSessionId ?? this.sessionRef;
21336
21413
  }
21337
21414
  runWithOperationTimeout(operation, callback, options = {}) {
21415
+ const timeoutPolicy = options.timeoutMs === void 0 ? this.policy.timeout : {
21416
+ resolveTimeoutMs() {
21417
+ return options.timeoutMs;
21418
+ }
21419
+ };
21338
21420
  const existingCollector = this.operationEventStorage.getStore();
21339
21421
  if (existingCollector !== void 0) {
21340
21422
  return runWithPolicyTimeout(
21341
- this.policy.timeout,
21423
+ timeoutPolicy,
21342
21424
  {
21343
21425
  operation,
21344
21426
  ...options.signal === void 0 ? {} : { signal: options.signal }
@@ -21351,7 +21433,7 @@ var OpensteerSessionRuntime = class {
21351
21433
  return this.operationEventStorage.run(collector, async () => {
21352
21434
  try {
21353
21435
  return await runWithPolicyTimeout(
21354
- this.policy.timeout,
21436
+ timeoutPolicy,
21355
21437
  {
21356
21438
  operation,
21357
21439
  ...options.signal === void 0 ? {} : { signal: options.signal }
@@ -21521,6 +21603,21 @@ function buildEngineNetworkRecordFilters(input) {
21521
21603
  function normalizeNetworkStatusFilter(status) {
21522
21604
  return String(status);
21523
21605
  }
21606
+ function normalizeNetworkQueryInput(input) {
21607
+ return {
21608
+ ...input,
21609
+ ...input.recordId === void 0 ? {} : { recordId: normalizeNetworkRecordId(input.recordId) },
21610
+ ...input.before === void 0 ? {} : { before: normalizeNetworkRecordId(input.before) },
21611
+ ...input.after === void 0 ? {} : { after: normalizeNetworkRecordId(input.after) }
21612
+ };
21613
+ }
21614
+ function normalizeNetworkRecordId(recordId) {
21615
+ const trimmed = recordId.trim();
21616
+ if (trimmed.length === 0 || trimmed.startsWith("record:")) {
21617
+ return trimmed;
21618
+ }
21619
+ return `record:${trimmed}`;
21620
+ }
21524
21621
  function resolveLiveQueryRequestIds(input, history) {
21525
21622
  const requestIdCandidates = [];
21526
21623
  if (input.recordId !== void 0) {
@@ -21733,6 +21830,20 @@ var REPLAY_TRANSPORT_LADDER = [
21733
21830
  "context-http",
21734
21831
  "page-http"
21735
21832
  ];
21833
+ function resolveReplayProbeAttemptTimeoutMs(input) {
21834
+ const attemptCapMs = input.recommendedFound ? REPLAY_PROBE_POST_SUCCESS_ATTEMPT_TIMEOUT_MS : REPLAY_PROBE_MAX_ATTEMPT_TIMEOUT_MS;
21835
+ const clampedRemaining = input.remainingMs === void 0 ? void 0 : Math.max(0, input.remainingMs);
21836
+ if (clampedRemaining === 0) {
21837
+ return 0;
21838
+ }
21839
+ if (clampedRemaining === void 0) {
21840
+ return attemptCapMs;
21841
+ }
21842
+ const sliceMs = Math.floor(clampedRemaining / Math.max(1, input.transportsRemaining));
21843
+ const minimumBudgetAffordable = clampedRemaining >= REPLAY_PROBE_MIN_ATTEMPT_TIMEOUT_MS * input.transportsRemaining;
21844
+ const attemptBudgetMs = minimumBudgetAffordable ? Math.max(REPLAY_PROBE_MIN_ATTEMPT_TIMEOUT_MS, sliceMs) : sliceMs;
21845
+ return Math.min(clampedRemaining, attemptCapMs, Math.max(1, attemptBudgetMs));
21846
+ }
21736
21847
  function filterNetworkSummaryRecords(records, input) {
21737
21848
  return records.filter((record) => {
21738
21849
  if (record.record.resourceType === "preflight" || record.record.method === "OPTIONS") {
@@ -21905,10 +22016,10 @@ function extractGraphqlOperationName(queryText) {
21905
22016
  function shouldShowRequestBody(method) {
21906
22017
  return !["GET", "HEAD", "DELETE", "OPTIONS"].includes(method.trim().toUpperCase());
21907
22018
  }
21908
- function buildStructuredBodyPreview(body, headers) {
22019
+ function buildStructuredBodyPreview(body, headers, options = {}) {
21909
22020
  const contentType = headerValue(headers, "content-type") ?? body?.mimeType;
21910
22021
  const parsed = parseStructuredPayload(body, contentType);
21911
- const data = parsed === void 0 ? void 0 : typeof parsed === "string" ? truncateInlineText(parsed) : truncateStructuredValue(parsed);
22022
+ const data = parsed === void 0 ? void 0 : options.truncateData === false ? parsed : typeof parsed === "string" ? truncateInlineText(parsed) : truncateStructuredValue(parsed);
21912
22023
  return {
21913
22024
  bytes: body?.originalByteLength ?? body?.capturedByteLength ?? 0,
21914
22025
  ...contentType === void 0 ? {} : { contentType },
@@ -22121,10 +22232,12 @@ function resolveSessionFetchTransportLadder(transport) {
22121
22232
  return ["direct-http"];
22122
22233
  case "matched-tls":
22123
22234
  return ["matched-tls"];
22235
+ case "context":
22236
+ return ["context-http"];
22124
22237
  case "page":
22125
22238
  return ["page-http"];
22126
22239
  case "auto":
22127
- return ["direct-http", "matched-tls", "page-http"];
22240
+ return ["direct-http", "matched-tls", "context-http", "page-http"];
22128
22241
  }
22129
22242
  }
22130
22243
  function detectChallengeNoteFromRecord(record) {
@@ -22269,6 +22382,12 @@ function diffStorageSnapshot(left, right) {
22269
22382
  function normalizeRuntimeErrorMessage(error) {
22270
22383
  return error instanceof Error ? error.message : String(error);
22271
22384
  }
22385
+ function normalizeProbeTransportAttemptError(transport, error, attemptTimeoutMs) {
22386
+ if (attemptTimeoutMs !== void 0 && error instanceof OpensteerProtocolError && error.code === "timeout") {
22387
+ return `${transport} probe exceeded ${String(attemptTimeoutMs)}ms`;
22388
+ }
22389
+ return normalizeRuntimeErrorMessage(error);
22390
+ }
22272
22391
  function applyBrowserCookiesToTransportRequest(request, cookies) {
22273
22392
  if (cookies.length === 0) {
22274
22393
  return request;
@@ -24803,9 +24922,11 @@ exports.createFilesystemOpensteerWorkspace = createFilesystemOpensteerWorkspace;
24803
24922
  exports.createFlowRecorderInstallScript = createFlowRecorderInstallScript;
24804
24923
  exports.createObservationStore = createObservationStore;
24805
24924
  exports.createOpensteerExtractionDescriptorStore = createOpensteerExtractionDescriptorStore;
24925
+ exports.createSavedNetworkStore = createSavedNetworkStore;
24806
24926
  exports.dispatchSemanticOperation = dispatchSemanticOperation;
24807
24927
  exports.generateReplayScript = generateReplayScript;
24808
24928
  exports.hashDomDescriptorPersist = hashDomDescriptorPersist;
24929
+ exports.iterateSavedNetworkRecordBatches = iterateSavedNetworkRecordBatches;
24809
24930
  exports.manifestToExternalBinaryLocation = manifestToExternalBinaryLocation;
24810
24931
  exports.normalizeObservabilityConfig = normalizeObservabilityConfig;
24811
24932
  exports.normalizeWorkspaceId = normalizeWorkspaceId;