@nuanu-ai/agentbrowse 0.2.36 → 0.2.38

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.
@@ -1 +1 @@
1
- {"version":3,"file":"close.d.ts","sourceRoot":"","sources":["../../src/commands/close.ts"],"names":[],"mappings":"AAAA;;GAEG;AAOH,MAAM,MAAM,kBAAkB,GAAG;IAC/B,OAAO,EAAE,IAAI,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,OAAO,EAAE,KAAK,CAAC;IACf,KAAK,EAAE,sBAAsB,CAAC;IAC9B,WAAW,EAAE,SAAS,CAAC;IACvB,OAAO,EAAE,uBAAuB,CAAC;IACjC,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,kBAAkB,GAAG,kBAAkB,CAAC;AAMlE,wBAAsB,KAAK,IAAI,OAAO,CAAC,WAAW,CAAC,CAwBlD"}
1
+ {"version":3,"file":"close.d.ts","sourceRoot":"","sources":["../../src/commands/close.ts"],"names":[],"mappings":"AAAA;;GAEG;AAQH,MAAM,MAAM,kBAAkB,GAAG;IAC/B,OAAO,EAAE,IAAI,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,OAAO,EAAE,KAAK,CAAC;IACf,KAAK,EAAE,sBAAsB,CAAC;IAC9B,WAAW,EAAE,SAAS,CAAC;IACvB,OAAO,EAAE,uBAAuB,CAAC;IACjC,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,kBAAkB,GAAG,kBAAkB,CAAC;AAclE,wBAAsB,KAAK,IAAI,OAAO,CAAC,WAAW,CAAC,CAwBlD"}
@@ -1,15 +1,22 @@
1
1
  /**
2
2
  * browse close — Close the browser and clean up session.
3
3
  */
4
- import { loadSession, deleteSession } from '../session.js';
4
+ import { deleteSession, isOwnedSession, loadSession } from '../session.js';
5
5
  import { info } from '../output.js';
6
6
  import { closeOwnedBrowser } from '../owned-browser.js';
7
- function isOwnedSessionRecord(session) {
8
- return session?.identity?.ownership === 'agentbrowse';
7
+ import { isManagedBrowserPid } from '../owned-process.js';
8
+ function isCloseableManagedSession(session) {
9
+ if (!session) {
10
+ return false;
11
+ }
12
+ if (isOwnedSession(session)) {
13
+ return true;
14
+ }
15
+ return !session.identity && isManagedBrowserPid(session.pid);
9
16
  }
10
17
  export async function close() {
11
18
  const session = loadSession();
12
- if (isOwnedSessionRecord(session)) {
19
+ if (isCloseableManagedSession(session)) {
13
20
  const closeResult = await closeOwnedBrowser(session);
14
21
  if (!closeResult.success) {
15
22
  info(`Owned browser close failed; keeping session record: ${closeResult.reason}`);
@@ -1 +1 @@
1
- {"version":3,"file":"observe-accessibility.d.ts","sourceRoot":"","sources":["../../src/commands/observe-accessibility.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAS5C,OAAO,KAAK,EAEV,iBAAiB,EAElB,MAAM,wBAAwB,CAAC;AAEhC,KAAK,6BAA6B,GAAG;IACnC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC,CAAC;CACpD,CAAC;AAOF,MAAM,MAAM,yBAAyB,GAAG;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,KAAK,2BAA2B,GAAG;IACjC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,yBAAyB,KAAK,IAAI,CAAC;CACtD,CAAC;AAyDF,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAClC,6BAA6B,GAAG,IAAI,CAoDtC;AA+nBD,wBAAsB,iCAAiC,CACrD,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,aAAa,CAAC,iBAAiB,CAAC,EACzC,OAAO,CAAC,EAAE,2BAA2B,GACpC,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAY9B;AAED,eAAO,MAAM,0BAA0B;;CAEtC,CAAC"}
1
+ {"version":3,"file":"observe-accessibility.d.ts","sourceRoot":"","sources":["../../src/commands/observe-accessibility.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAa5C,OAAO,KAAK,EAEV,iBAAiB,EAElB,MAAM,wBAAwB,CAAC;AAEhC,KAAK,6BAA6B,GAAG;IACnC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC,CAAC;CACpD,CAAC;AAOF,MAAM,MAAM,yBAAyB,GAAG;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,KAAK,2BAA2B,GAAG;IACjC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,yBAAyB,KAAK,IAAI,CAAC;CACtD,CAAC;AAoEF,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAClC,6BAA6B,GAAG,IAAI,CAoDtC;AAkrBD,wBAAsB,iCAAiC,CACrD,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,aAAa,CAAC,iBAAiB,CAAC,EACzC,OAAO,CAAC,EAAE,2BAA2B,GACpC,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAY9B;AAED,eAAO,MAAM,0BAA0B;;CAEtC,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import { resolveLocatorRoot } from './action-fallbacks.js';
2
2
  import { buildObserveDisplayLabel } from './observe-display-label.js';
3
+ import { isButtonLikeObservedInput, shouldAllowLooseFieldLabelFallbackForObservedControl, } from './observe-label-policy.js';
3
4
  import { fallbackContextNodeLabelOf, fallbackHintTextOf, fallbackSurfaceLabelOf, fallbackTargetLabelOf, } from './observe-fallback-semantics.js';
4
5
  const AX_ENRICHMENT_CONCURRENCY = 12;
5
6
  const AX_SNAPSHOT_TIMEOUT_MS = 250;
@@ -18,6 +19,17 @@ const GENERIC_FALLBACK_LABELS = new Set([
18
19
  'menu item',
19
20
  'grid cell',
20
21
  ]);
22
+ const GENERIC_CONTAINER_AX_NAMES = new Set([
23
+ 'alertdialog',
24
+ 'article',
25
+ 'complementary',
26
+ 'dialog',
27
+ 'form',
28
+ 'group',
29
+ 'main',
30
+ 'region',
31
+ 'search',
32
+ ]);
21
33
  const NON_CONTAINER_AX_ROLES = new Set([
22
34
  'button',
23
35
  'checkbox',
@@ -105,12 +117,39 @@ function shouldPreferAccessibilityName(target, accessibilityName) {
105
117
  const currentKey = normalizeLabelKey(currentLabel);
106
118
  const nextLabel = normalizeText(accessibilityName);
107
119
  const visibleText = normalizeText(target.text);
120
+ const kind = normalizeText(target.kind)?.toLowerCase();
121
+ const role = normalizeText(target.role)?.toLowerCase();
122
+ const looseFieldFallbackAllowed = shouldAllowLooseFieldLabelFallbackForObservedControl({
123
+ tag: kind,
124
+ role,
125
+ inputType: target.inputType,
126
+ });
127
+ const primaryAxControl = !looseFieldFallbackAllowed &&
128
+ (kind === 'button' ||
129
+ kind === 'link' ||
130
+ kind === 'checkbox' ||
131
+ kind === 'radio' ||
132
+ role === 'button' ||
133
+ role === 'link' ||
134
+ role === 'checkbox' ||
135
+ role === 'radio' ||
136
+ role === 'menuitem' ||
137
+ role === 'option' ||
138
+ role === 'switch' ||
139
+ role === 'tab' ||
140
+ isButtonLikeObservedInput({
141
+ tag: kind,
142
+ inputType: target.inputType,
143
+ }));
108
144
  if (!isMeaningfulName(nextLabel)) {
109
145
  return false;
110
146
  }
111
147
  if (!isMeaningfulName(currentLabel)) {
112
148
  return true;
113
149
  }
150
+ if (primaryAxControl && currentLabel !== nextLabel) {
151
+ return true;
152
+ }
114
153
  if (GENERIC_FALLBACK_LABELS.has(currentKey)) {
115
154
  return true;
116
155
  }
@@ -322,6 +361,16 @@ function shouldUseContainerAccessibilityName(expectedKind, semantics) {
322
361
  return false;
323
362
  }
324
363
  function chooseContainerSemanticName(fallbackValue, expectedKind, semantics, stats) {
364
+ const normalizedFallback = normalizeText(fallbackValue);
365
+ const normalizedSemanticName = normalizeLabelKey(semantics?.name);
366
+ const normalizedSemanticRole = normalizedContainerKind(semantics?.role);
367
+ if (isMeaningfulName(normalizedFallback) &&
368
+ (!isMeaningfulName(normalizedSemanticName) ||
369
+ GENERIC_CONTAINER_AX_NAMES.has(normalizedSemanticName) ||
370
+ normalizedSemanticName === normalizedSemanticRole)) {
371
+ stats.fallbackUses += 1;
372
+ return fallbackValue;
373
+ }
325
374
  if (shouldUseContainerAccessibilityName(expectedKind, semantics)) {
326
375
  return semantics?.name;
327
376
  }
@@ -334,10 +383,17 @@ function enrichContextNode(node, semantics, domFallback, stats) {
334
383
  if (!node) {
335
384
  return undefined;
336
385
  }
386
+ const fallbackLabel = [
387
+ fallbackContextNodeLabelOf(node),
388
+ node.text,
389
+ domFallback?.label,
390
+ ]
391
+ .map((value) => normalizeText(value))
392
+ .find(isMeaningfulName);
337
393
  return {
338
394
  ...node,
339
395
  kind: node.kind ?? semantics?.role,
340
- label: chooseContainerSemanticName(fallbackContextNodeLabelOf(node) ?? domFallback?.label, node.kind, semantics, stats),
396
+ label: chooseContainerSemanticName(fallbackLabel, node.kind, semantics, stats),
341
397
  };
342
398
  }
343
399
  function chooseHintText(context, nextContext, domFallbackHint, stats) {
@@ -426,7 +482,13 @@ async function enrichTargetWithAccessibility(page, target, rootCache, snapshotCa
426
482
  const landmarkDomFallback = await readDomFallbackSemantics(page, { selector: target.context?.landmark?.selector, framePath: target.framePath }, rootCache, fallbackCache);
427
483
  const targetDomFallback = await readDomFallbackSemantics(page, target, rootCache, fallbackCache);
428
484
  const nextLabel = isMeaningfulName(semantics?.name) &&
429
- shouldPreferAccessibilityName({ label: fallbackTargetLabelOf(target), text: target.text }, semantics.name)
485
+ shouldPreferAccessibilityName({
486
+ kind: target.kind,
487
+ role: target.role,
488
+ inputType: target.inputType,
489
+ label: fallbackTargetLabelOf(target),
490
+ text: target.text,
491
+ }, semantics.name)
430
492
  ? semantics.name
431
493
  : chooseSemanticName(fallbackTargetLabelOf(target), semantics, stats);
432
494
  const nextContext = target.context
@@ -1 +1 @@
1
- {"version":3,"file":"observe-inventory.d.ts","sourceRoot":"","sources":["../../src/commands/observe-inventory.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"observe-inventory.d.ts","sourceRoot":"","sources":["../../src/commands/observe-inventory.ts"],"names":[],"mappings":"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"}
@@ -1756,7 +1756,12 @@ async function collectDomTargetsFromDocument(context, options) {
1756
1756
  const role = inferRole(element) || '';
1757
1757
  const className = (element.getAttribute('class') || '').toLowerCase();
1758
1758
  const surfaceKind = inferSurfaceKind(surface);
1759
- const label = explicitLabelOf(element) || textOf(element) || syntheticLabelOf(element) || '';
1759
+ const seatValueLabel =
1760
+ element.getAttribute('data-seat-value')?.trim() ||
1761
+ element.getAttribute('data-seat')?.trim() ||
1762
+ undefined;
1763
+ const label =
1764
+ explicitLabelOf(element) || textOf(element) || seatValueLabel || syntheticLabelOf(element) || '';
1760
1765
  const normalizedLabel = label.replace(/\s+/g, ' ').trim();
1761
1766
  const explicitDateCellMetadata =
1762
1767
  element.hasAttribute('data-day') ||
@@ -2025,6 +2030,14 @@ async function collectDomTargetsFromDocument(context, options) {
2025
2030
  }
2026
2031
  }
2027
2032
 
2033
+ return undefined;
2034
+ };
2035
+
2036
+ const contextTextOf = (element) => {
2037
+ if (!isHTMLElementNode(element)) {
2038
+ return undefined;
2039
+ }
2040
+
2028
2041
  const text = textOf(element, { container: true });
2029
2042
  if (!text) {
2030
2043
  return undefined;
@@ -2036,14 +2049,19 @@ async function collectDomTargetsFromDocument(context, options) {
2036
2049
  if (!element) return undefined;
2037
2050
 
2038
2051
  const kind = element.getAttribute?.('role')?.trim() || element.tagName?.toLowerCase?.();
2039
- const label = contextLabelOf(element);
2052
+ const fallbackLabel = contextLabelOf(element);
2053
+ const text = contextTextOf(element);
2040
2054
  const selector = buildSelector(element);
2041
- if (!kind && !label && !selector) return undefined;
2055
+ if (!kind && !fallbackLabel && !text && !selector) return undefined;
2042
2056
  return {
2043
2057
  kind: kind || undefined,
2044
- label,
2045
- text: undefined,
2058
+ label: undefined,
2059
+ text:
2060
+ text && (!fallbackLabel || text.toLowerCase() !== fallbackLabel.toLowerCase())
2061
+ ? text
2062
+ : undefined,
2046
2063
  selector,
2064
+ fallbackLabel,
2047
2065
  };
2048
2066
  };
2049
2067
 
@@ -2101,7 +2119,7 @@ async function collectDomTargetsFromDocument(context, options) {
2101
2119
  }
2102
2120
 
2103
2121
  const rect = element.getBoundingClientRect();
2104
- if (rect.width < 220 || rect.height < 220) {
2122
+ if (rect.width < 220 || rect.height < 160) {
2105
2123
  return false;
2106
2124
  }
2107
2125
 
@@ -2180,6 +2198,56 @@ async function collectDomTargetsFromDocument(context, options) {
2180
2198
  return states;
2181
2199
  };
2182
2200
 
2201
+ const visualSeatIdentityOf = (element) => {
2202
+ const explicitRow = element.getAttribute('data-row')?.trim();
2203
+ const explicitColumn = element.getAttribute('data-column')?.trim().toUpperCase();
2204
+ if (explicitRow && explicitColumn) {
2205
+ return {
2206
+ row: explicitRow,
2207
+ column: explicitColumn,
2208
+ label: explicitRow + explicitColumn,
2209
+ };
2210
+ }
2211
+
2212
+ const candidates = [
2213
+ element.getAttribute('data-seat-value'),
2214
+ element.getAttribute('data-seat'),
2215
+ element.getAttribute('aria-label'),
2216
+ element.getAttribute('title'),
2217
+ ];
2218
+
2219
+ for (const candidate of candidates) {
2220
+ const normalized = compactText(candidate);
2221
+ if (!normalized) {
2222
+ continue;
2223
+ }
2224
+
2225
+ const rowColumnMatch = normalized.match(/(?:^|\b)(\d{1,3})\s*([a-z])(?:\b|$)/i);
2226
+ if (rowColumnMatch) {
2227
+ const row = rowColumnMatch[1];
2228
+ const column = rowColumnMatch[2].toUpperCase();
2229
+ return {
2230
+ row,
2231
+ column,
2232
+ label: row + column,
2233
+ };
2234
+ }
2235
+
2236
+ const columnRowMatch = normalized.match(/(?:^|\b)([a-z])\s*(\d{1,3})(?:\b|$)/i);
2237
+ if (columnRowMatch) {
2238
+ const row = columnRowMatch[2];
2239
+ const column = columnRowMatch[1].toUpperCase();
2240
+ return {
2241
+ row,
2242
+ column,
2243
+ label: row + column,
2244
+ };
2245
+ }
2246
+ }
2247
+
2248
+ return undefined;
2249
+ };
2250
+
2183
2251
  const isVisualSeatCellElement = (element) => {
2184
2252
  if (!isVisualGridSquareElement(element)) {
2185
2253
  return false;
@@ -2344,6 +2412,7 @@ async function collectDomTargetsFromDocument(context, options) {
2344
2412
  const descriptors = [];
2345
2413
 
2346
2414
  for (const seatCell of seatCells) {
2415
+ const explicitSeatIdentity = visualSeatIdentityOf(seatCell.element);
2347
2416
  const rowHeaderCandidates = rowHeaders.filter((header) => {
2348
2417
  const headerCenterY = header.rect.top + header.rect.height / 2;
2349
2418
  const seatCenterY = seatCell.rect.top + seatCell.rect.height / 2;
@@ -2358,19 +2427,26 @@ async function collectDomTargetsFromDocument(context, options) {
2358
2427
  seatCell.rect,
2359
2428
  'row'
2360
2429
  ) || undefined;
2361
- const columnHeader = chooseNearestHeader(
2362
- topColumnHeaders.filter((header) => header.rect.bottom <= seatCell.rect.top + 12),
2363
- seatCell.rect,
2364
- 'column'
2430
+ const columnHeaderCandidates = topColumnHeaders.filter(
2431
+ (header) => header.rect.bottom <= seatCell.rect.top + 12
2365
2432
  );
2366
-
2367
- const row = rowHeader?.text;
2368
- const column = columnHeader?.text;
2433
+ const columnHeader =
2434
+ explicitSeatIdentity?.column ||
2435
+ !topColumnHeaders.length
2436
+ ? undefined
2437
+ : chooseNearestHeader(
2438
+ columnHeaderCandidates.length > 0 ? columnHeaderCandidates : topColumnHeaders,
2439
+ seatCell.rect,
2440
+ 'column'
2441
+ );
2442
+
2443
+ const row = explicitSeatIdentity?.row || rowHeader?.text;
2444
+ const column = explicitSeatIdentity?.column || columnHeader?.text;
2369
2445
  if (!row || !column) {
2370
2446
  continue;
2371
2447
  }
2372
2448
 
2373
- const label = row + column;
2449
+ const label = explicitSeatIdentity?.label || row + column;
2374
2450
  const states = visualSeatCellStateOf(seatCell.element);
2375
2451
  descriptors.push({
2376
2452
  element: seatCell.element,
@@ -2643,7 +2719,7 @@ async function collectDomTargetsFromDocument(context, options) {
2643
2719
  lane: laneOf(rect),
2644
2720
  band: bandOf(rect),
2645
2721
  },
2646
- hintText: undefined,
2722
+ hintText: describedByTextOf(element),
2647
2723
  fallbackHintText: visualSeatGrid?.hintText,
2648
2724
  visual: visualOf(element),
2649
2725
  },
@@ -1 +1 @@
1
- {"version":3,"file":"observe-surfaces.d.ts","sourceRoot":"","sources":["../../src/commands/observe-surfaces.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,gBAAgB,EAChB,iBAAiB,EACjB,aAAa,EACb,gBAAgB,EACjB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AA6ChE,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,aAAa,CAAC,iBAAiB,CAAC,EACxC,OAAO,EAAE,aAAa,CACpB,IAAI,CAAC,gBAAgB,EAAE,YAAY,GAAG,gBAAgB,GAAG,kBAAkB,CAAC,CAC7E,EACD,kBAAkB,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,GACvC,iBAAiB,EAAE,CAiDrB;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,GAAG,SAAS,CAa7E;AAyBD,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,IAAI,CACV,iBAAiB,EACjB,eAAe,GAAG,WAAW,GAAG,UAAU,GAAG,cAAc,GAAG,SAAS,CACxE,GACA,MAAM,GAAG,SAAS,CAkBpB;AAED,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,IAAI,CAAC,iBAAiB,EAAE,SAAS,GAAG,eAAe,GAAG,WAAW,GAAG,MAAM,GAAG,OAAO,CAAC,GAC7F,MAAM,CAMR;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,aAAa,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CA4CvF;AAED,wBAAgB,0BAA0B,CACxC,GAAG,EAAE,gBAAgB,EAAE,EACvB,SAAS,EAAE,gBAAgB,GAAG,SAAS,GACtC,IAAI,CAON;AAwDD,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,aAAa,CAAC,iBAAiB,CAAC,oCAyE1C"}
1
+ {"version":3,"file":"observe-surfaces.d.ts","sourceRoot":"","sources":["../../src/commands/observe-surfaces.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,gBAAgB,EAChB,iBAAiB,EACjB,aAAa,EACb,gBAAgB,EACjB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AA6ChE,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,aAAa,CAAC,iBAAiB,CAAC,EACxC,OAAO,EAAE,aAAa,CACpB,IAAI,CAAC,gBAAgB,EAAE,YAAY,GAAG,gBAAgB,GAAG,kBAAkB,CAAC,CAC7E,EACD,kBAAkB,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,GACvC,iBAAiB,EAAE,CAiDrB;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,GAAG,SAAS,CAa7E;AAyBD,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,IAAI,CACV,iBAAiB,EACjB,eAAe,GAAG,WAAW,GAAG,UAAU,GAAG,cAAc,GAAG,SAAS,CACxE,GACA,MAAM,GAAG,SAAS,CAkBpB;AAED,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,IAAI,CAAC,iBAAiB,EAAE,SAAS,GAAG,eAAe,GAAG,WAAW,GAAG,MAAM,GAAG,OAAO,CAAC,GAC7F,MAAM,CAMR;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,aAAa,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CA8BvF;AAED,wBAAgB,0BAA0B,CACxC,GAAG,EAAE,gBAAgB,EAAE,EACvB,SAAS,EAAE,gBAAgB,GAAG,SAAS,GACtC,IAAI,CAON;AAwDD,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,aAAa,CAAC,iBAAiB,CAAC,oCAyE1C"}
@@ -133,37 +133,23 @@ export function summarizeContext(context) {
133
133
  if (!context)
134
134
  return undefined;
135
135
  const parts = [];
136
- if (context.item?.label) {
137
- parts.push(context.item.label);
138
- }
139
- else if (context.item?.kind) {
140
- parts.push(context.item.kind);
141
- }
142
- if (context.group?.label) {
143
- parts.push(context.group.label);
144
- }
145
- else if (context.group?.kind) {
146
- parts.push(context.group.kind);
147
- }
148
- if (parts.length === 0 && context.container?.label) {
149
- parts.push(context.container.label);
150
- }
151
- else if (parts.length === 0 && context.container?.kind) {
152
- parts.push(context.container.kind);
153
- }
154
- if (context.landmark?.label &&
155
- context.landmark.label !== context.container?.label &&
156
- context.landmark.label !== context.group?.label) {
157
- parts.push(context.landmark.label);
136
+ const pushIfDistinct = (value) => {
137
+ const normalized = normalizeSurfaceText(value);
138
+ if (!normalized || parts.includes(normalized)) {
139
+ return;
140
+ }
141
+ parts.push(normalized);
142
+ };
143
+ pushIfDistinct(context.item?.label ?? context.item?.text ?? context.item?.kind);
144
+ pushIfDistinct(context.group?.label ?? context.group?.text ?? context.group?.kind);
145
+ if (parts.length === 0) {
146
+ pushIfDistinct(context.container?.label ?? context.container?.text ?? context.container?.kind);
158
147
  }
159
- else if (context.landmark?.kind &&
160
- context.landmark.kind !== context.container?.kind &&
161
- context.landmark.kind !== context.group?.kind &&
162
- !context.landmark?.label) {
163
- parts.push(context.landmark.kind);
148
+ if (parts.length === 0 || context.landmark?.label || context.landmark?.text) {
149
+ pushIfDistinct(context.landmark?.label ?? context.landmark?.text ?? context.landmark?.kind);
164
150
  }
165
151
  if (parts.length === 0 && context.hintText) {
166
- parts.push(context.hintText);
152
+ pushIfDistinct(context.hintText);
167
153
  }
168
154
  if (parts.length === 0)
169
155
  return undefined;
@@ -0,0 +1,31 @@
1
+ export type SemanticObserveAnalyzerKey = 'en' | 'ru' | 'neutral';
2
+ export type SemanticObserveLexicalField = {
3
+ value?: string;
4
+ weight: number;
5
+ };
6
+ export type SemanticObserveAnalyzedText = {
7
+ analyzerKey: SemanticObserveAnalyzerKey;
8
+ normalizedText?: string;
9
+ terms: string[];
10
+ };
11
+ export type SemanticObserveLexicalDocument = {
12
+ analyzerKey: SemanticObserveAnalyzerKey;
13
+ weightedLength: number;
14
+ weightedTermFrequencies: Map<string, number>;
15
+ };
16
+ export type SemanticObserveBm25CorpusStats = {
17
+ averageDocumentLength: number;
18
+ documentCount: number;
19
+ documentFrequencyByTerm: Map<string, number>;
20
+ };
21
+ export declare function assertSemanticObserveRuntimeSupport(): void;
22
+ export declare function normalizeSemanticObserveText(value: string | undefined): string | undefined;
23
+ export declare function dominantSemanticObserveAnalyzerKey(value: string | undefined): SemanticObserveAnalyzerKey;
24
+ export declare function analyzeSemanticObserveText(value: string | undefined): SemanticObserveAnalyzedText;
25
+ export declare function buildSemanticObserveLexicalDocument(fields: ReadonlyArray<SemanticObserveLexicalField>): SemanticObserveLexicalDocument;
26
+ export declare function buildSemanticObserveBm25CorpusStats(documents: ReadonlyArray<SemanticObserveLexicalDocument>): SemanticObserveBm25CorpusStats;
27
+ export declare function scoreSemanticObserveBm25(query: SemanticObserveAnalyzedText, document: SemanticObserveLexicalDocument, corpus: SemanticObserveBm25CorpusStats, options?: {
28
+ k1?: number;
29
+ b?: number;
30
+ }): number;
31
+ //# sourceMappingURL=semantic-observe-lexical.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"semantic-observe-lexical.d.ts","sourceRoot":"","sources":["../../src/commands/semantic-observe-lexical.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,0BAA0B,GAAG,IAAI,GAAG,IAAI,GAAG,SAAS,CAAC;AAEjE,MAAM,MAAM,2BAA2B,GAAG;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,2BAA2B,GAAG;IACxC,WAAW,EAAE,0BAA0B,CAAC;IACxC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,8BAA8B,GAAG;IAC3C,WAAW,EAAE,0BAA0B,CAAC;IACxC,cAAc,EAAE,MAAM,CAAC;IACvB,uBAAuB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9C,CAAC;AAEF,MAAM,MAAM,8BAA8B,GAAG;IAC3C,qBAAqB,EAAE,MAAM,CAAC;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,uBAAuB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9C,CAAC;AAMF,wBAAgB,mCAAmC,IAAI,IAAI,CAM1D;AAgDD,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAO1F;AAED,wBAAgB,kCAAkC,CAChD,KAAK,EAAE,MAAM,GAAG,SAAS,GACxB,0BAA0B,CAwB5B;AAmCD,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,2BAA2B,CAqBjG;AAED,wBAAgB,mCAAmC,CACjD,MAAM,EAAE,aAAa,CAAC,2BAA2B,CAAC,GACjD,8BAA8B,CAoChC;AAED,wBAAgB,mCAAmC,CACjD,SAAS,EAAE,aAAa,CAAC,8BAA8B,CAAC,GACvD,8BAA8B,CAiBhC;AAED,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,2BAA2B,EAClC,QAAQ,EAAE,8BAA8B,EACxC,MAAM,EAAE,8BAA8B,EACtC,OAAO,GAAE;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,CAAC,EAAE,MAAM,CAAA;CAAO,GACxC,MAAM,CA0BR"}
@@ -0,0 +1,188 @@
1
+ import { newStemmer } from 'snowball-stemmers';
2
+ const TOKENIZER_FALLBACK_RE = /[\p{L}\p{N}]+/gu;
3
+ const segmenterCache = new Map();
4
+ const stemmerCache = new Map();
5
+ export function assertSemanticObserveRuntimeSupport() {
6
+ if (typeof Intl === 'undefined' || typeof Intl.Segmenter !== 'function') {
7
+ throw new Error('AgentBrowse requires Intl.Segmenter. Use a modern Node runtime with standard Intl support.');
8
+ }
9
+ }
10
+ function segmenterFor(locale) {
11
+ const cached = segmenterCache.get(locale);
12
+ if (cached !== undefined) {
13
+ return cached;
14
+ }
15
+ assertSemanticObserveRuntimeSupport();
16
+ const segmenter = new Intl.Segmenter(locale === 'neutral' ? undefined : locale, {
17
+ granularity: 'word',
18
+ });
19
+ segmenterCache.set(locale, segmenter);
20
+ return segmenter;
21
+ }
22
+ function stemmerFor(locale) {
23
+ const cached = stemmerCache.get(locale);
24
+ if (cached !== undefined) {
25
+ return cached;
26
+ }
27
+ const algorithm = locale === 'en' ? 'english' : locale === 'ru' ? 'russian' : undefined;
28
+ if (!algorithm) {
29
+ stemmerCache.set(locale, null);
30
+ return null;
31
+ }
32
+ const stemmer = newStemmer(algorithm);
33
+ stemmerCache.set(locale, stemmer);
34
+ return stemmer;
35
+ }
36
+ function isNumericToken(token) {
37
+ return /^[\p{N}]+$/u.test(token);
38
+ }
39
+ function detectAnalyzerKeyForToken(token) {
40
+ if (/[\p{Script=Cyrillic}]/u.test(token)) {
41
+ return 'ru';
42
+ }
43
+ if (/[\p{Script=Latin}]/u.test(token)) {
44
+ return 'en';
45
+ }
46
+ return 'neutral';
47
+ }
48
+ export function normalizeSemanticObserveText(value) {
49
+ const normalized = value
50
+ ?.normalize('NFKC')
51
+ .replace(/\s+/g, ' ')
52
+ .trim()
53
+ .toLowerCase();
54
+ return normalized ? normalized : undefined;
55
+ }
56
+ export function dominantSemanticObserveAnalyzerKey(value) {
57
+ const normalized = normalizeSemanticObserveText(value);
58
+ if (!normalized) {
59
+ return 'neutral';
60
+ }
61
+ let latinCount = 0;
62
+ let cyrillicCount = 0;
63
+ for (const token of normalized.match(TOKENIZER_FALLBACK_RE) ?? []) {
64
+ const key = detectAnalyzerKeyForToken(token);
65
+ if (key === 'en') {
66
+ latinCount += 1;
67
+ }
68
+ else if (key === 'ru') {
69
+ cyrillicCount += 1;
70
+ }
71
+ }
72
+ if (cyrillicCount > latinCount) {
73
+ return 'ru';
74
+ }
75
+ if (latinCount > 0) {
76
+ return 'en';
77
+ }
78
+ return 'neutral';
79
+ }
80
+ function segmentSemanticObserveText(normalizedText, locale) {
81
+ const segmenter = segmenterFor(locale);
82
+ const tokens = [];
83
+ for (const segment of segmenter.segment(normalizedText)) {
84
+ if (segment.isWordLike === false) {
85
+ continue;
86
+ }
87
+ const token = normalizeSemanticObserveText(segment.segment);
88
+ if (!token) {
89
+ continue;
90
+ }
91
+ if (!/[\p{L}\p{N}]/u.test(token)) {
92
+ continue;
93
+ }
94
+ tokens.push(token);
95
+ }
96
+ return tokens;
97
+ }
98
+ function stemSemanticObserveToken(token) {
99
+ const analyzerKey = detectAnalyzerKeyForToken(token);
100
+ const stemmer = stemmerFor(analyzerKey);
101
+ if (!stemmer) {
102
+ return token;
103
+ }
104
+ const stemmed = normalizeSemanticObserveText(stemmer.stem(token));
105
+ return stemmed && (stemmed.length >= 2 || isNumericToken(stemmed)) ? stemmed : token;
106
+ }
107
+ export function analyzeSemanticObserveText(value) {
108
+ const normalizedText = normalizeSemanticObserveText(value);
109
+ if (!normalizedText) {
110
+ return {
111
+ analyzerKey: 'neutral',
112
+ normalizedText: undefined,
113
+ terms: [],
114
+ };
115
+ }
116
+ const analyzerKey = dominantSemanticObserveAnalyzerKey(normalizedText);
117
+ const segmented = segmentSemanticObserveText(normalizedText, analyzerKey);
118
+ const terms = segmented
119
+ .map((token) => stemSemanticObserveToken(token))
120
+ .filter((token) => token.length >= 2 || isNumericToken(token));
121
+ return {
122
+ analyzerKey,
123
+ normalizedText,
124
+ terms,
125
+ };
126
+ }
127
+ export function buildSemanticObserveLexicalDocument(fields) {
128
+ const weightedTermFrequencies = new Map();
129
+ const analyzerVotes = new Map();
130
+ let weightedLength = 0;
131
+ for (const field of fields) {
132
+ if (field.weight <= 0) {
133
+ continue;
134
+ }
135
+ const analyzed = analyzeSemanticObserveText(field.value);
136
+ if (analyzed.terms.length === 0) {
137
+ continue;
138
+ }
139
+ analyzerVotes.set(analyzed.analyzerKey, (analyzerVotes.get(analyzed.analyzerKey) ?? 0) + analyzed.terms.length);
140
+ weightedLength += analyzed.terms.length * field.weight;
141
+ for (const term of analyzed.terms) {
142
+ weightedTermFrequencies.set(term, (weightedTermFrequencies.get(term) ?? 0) + field.weight);
143
+ }
144
+ }
145
+ const analyzerKey = [...analyzerVotes.entries()].sort((left, right) => right[1] - left[1])[0]?.[0] ?? 'neutral';
146
+ return {
147
+ analyzerKey,
148
+ weightedLength,
149
+ weightedTermFrequencies,
150
+ };
151
+ }
152
+ export function buildSemanticObserveBm25CorpusStats(documents) {
153
+ const documentFrequencyByTerm = new Map();
154
+ let totalLength = 0;
155
+ for (const document of documents) {
156
+ totalLength += document.weightedLength;
157
+ for (const term of document.weightedTermFrequencies.keys()) {
158
+ documentFrequencyByTerm.set(term, (documentFrequencyByTerm.get(term) ?? 0) + 1);
159
+ }
160
+ }
161
+ return {
162
+ averageDocumentLength: documents.length > 0 ? totalLength / documents.length : 0,
163
+ documentCount: documents.length,
164
+ documentFrequencyByTerm,
165
+ };
166
+ }
167
+ export function scoreSemanticObserveBm25(query, document, corpus, options = {}) {
168
+ if (query.terms.length === 0 || document.weightedTermFrequencies.size === 0 || corpus.documentCount === 0) {
169
+ return 0;
170
+ }
171
+ const k1 = options.k1 ?? 1.2;
172
+ const b = options.b ?? 0.75;
173
+ const averageDocumentLength = Math.max(corpus.averageDocumentLength, 1);
174
+ const documentLength = Math.max(document.weightedLength, 1);
175
+ const uniqueTerms = [...new Set(query.terms)];
176
+ let score = 0;
177
+ for (const term of uniqueTerms) {
178
+ const termFrequency = document.weightedTermFrequencies.get(term) ?? 0;
179
+ if (termFrequency <= 0) {
180
+ continue;
181
+ }
182
+ const documentFrequency = corpus.documentFrequencyByTerm.get(term) ?? 0;
183
+ const idf = Math.log(1 + (corpus.documentCount - documentFrequency + 0.5) / (documentFrequency + 0.5));
184
+ const denominator = termFrequency + k1 * (1 - b + b * (documentLength / averageDocumentLength));
185
+ score += idf * ((termFrequency * (k1 + 1)) / denominator);
186
+ }
187
+ return score;
188
+ }
@@ -24,6 +24,7 @@ type ObserveInventoryTarget = {
24
24
  pageSignature?: string;
25
25
  goalInventoryType?: 'target' | 'scope';
26
26
  goalSurfaceId?: string;
27
+ controlsSurfaceSelector?: string;
27
28
  };
28
29
  export declare function rerankDomTargetsForGoal<T extends ObserveInventoryTarget>(instruction: string, targets: ReadonlyArray<T>, options?: {
29
30
  session?: BrowseSession;
@@ -1 +1 @@
1
- {"version":3,"file":"semantic-observe.d.ts","sourceRoot":"","sources":["../../src/commands/semantic-observe.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEnD,OAAO,KAAK,EACV,sBAAsB,EACtB,mBAAmB,EACnB,gBAAgB,EAChB,aAAa,EACb,mBAAmB,EACnB,eAAe,EAChB,MAAM,qBAAqB,CAAC;AAE7B,KAAK,sBAAsB,GAAG;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC,CAAC;IACnD,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,cAAc,CAAC,EAAE,mBAAmB,EAAE,CAAC;IACvC,gBAAgB,CAAC,EAAE,sBAAsB,CAAC;IAC1C,aAAa,CAAC,EAAE,mBAAmB,CAAC;IACpC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iBAAiB,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC;IACvC,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAwhCF,wBAAsB,uBAAuB,CAAC,CAAC,SAAS,sBAAsB,EAC5E,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,EACzB,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,aAAa,CAAA;CAAO,GACxC,OAAO,CAAC,CAAC,EAAE,CAAC,CA0Ed"}
1
+ {"version":3,"file":"semantic-observe.d.ts","sourceRoot":"","sources":["../../src/commands/semantic-observe.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEnD,OAAO,KAAK,EACV,sBAAsB,EACtB,mBAAmB,EACnB,gBAAgB,EAChB,aAAa,EACb,mBAAmB,EACnB,eAAe,EAChB,MAAM,qBAAqB,CAAC;AAY7B,KAAK,sBAAsB,GAAG;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC,CAAC;IACnD,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,cAAc,CAAC,EAAE,mBAAmB,EAAE,CAAC;IACvC,gBAAgB,CAAC,EAAE,sBAAsB,CAAC;IAC1C,aAAa,CAAC,EAAE,mBAAmB,CAAC;IACpC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iBAAiB,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC;IACvC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,uBAAuB,CAAC,EAAE,MAAM,CAAC;CAClC,CAAC;AAwoCF,wBAAsB,uBAAuB,CAAC,CAAC,SAAS,sBAAsB,EAC5E,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,EACzB,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,aAAa,CAAA;CAAO,GACxC,OAAO,CAAC,CAAC,EAAE,CAAC,CA2Ed"}