unbrowse 9.5.0 → 9.6.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "unbrowse",
3
- "version": "9.5.0",
3
+ "version": "9.6.1",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/unbrowse-ai/unbrowse.git"
package/runtime/cli.js CHANGED
@@ -1730,6 +1730,69 @@ var init_cached_resolution = __esm(() => {
1730
1730
  init_principal_scope();
1731
1731
  });
1732
1732
 
1733
+ // .tmp-runtime-src/values/cardinality.ts
1734
+ function isListLikeIntent(intent) {
1735
+ return LIST_INTENT_RE.test(intent ?? "");
1736
+ }
1737
+ function valueLooksLikeSingleItem(value) {
1738
+ if (value == null || Array.isArray(value) || typeof value !== "object")
1739
+ return false;
1740
+ const obj = value;
1741
+ for (const key of COLLECTION_KEYS) {
1742
+ if (Array.isArray(obj[key]))
1743
+ return false;
1744
+ }
1745
+ for (const v of Object.values(obj)) {
1746
+ if (Array.isArray(v) && v.some((x) => x !== null && typeof x === "object"))
1747
+ return false;
1748
+ }
1749
+ const atType = typeof obj["@type"] === "string" ? obj["@type"].toLowerCase() : "";
1750
+ const isItemType = ITEM_SCHEMA_TYPES.has(atType);
1751
+ const hasName = "name" in obj || "title" in obj || "headline" in obj;
1752
+ const hasPriceish = "offers" in obj || "price" in obj || "sku" in obj;
1753
+ return isItemType || hasName && hasPriceish;
1754
+ }
1755
+ function resolutionCardinalityMatches(intent, data) {
1756
+ if (!isListLikeIntent(intent))
1757
+ return true;
1758
+ return !valueLooksLikeSingleItem(data);
1759
+ }
1760
+ var LIST_INTENT_RE, ITEM_SCHEMA_TYPES, COLLECTION_KEYS;
1761
+ var init_cardinality = __esm(() => {
1762
+ LIST_INTENT_RE = /\b(search|find|lookup|browse|discover|list(?:ings?)?|feed|catalog(?:ue)?)\b/i;
1763
+ ITEM_SCHEMA_TYPES = new Set([
1764
+ "product",
1765
+ "offer",
1766
+ "article",
1767
+ "newsarticle",
1768
+ "blogposting",
1769
+ "recipe",
1770
+ "event",
1771
+ "place",
1772
+ "localbusiness",
1773
+ "jobposting",
1774
+ "book",
1775
+ "movie",
1776
+ "creativework",
1777
+ "person",
1778
+ "organization"
1779
+ ]);
1780
+ COLLECTION_KEYS = [
1781
+ "itemListElement",
1782
+ "items",
1783
+ "results",
1784
+ "products",
1785
+ "listings",
1786
+ "data",
1787
+ "edges",
1788
+ "hits",
1789
+ "records",
1790
+ "entries",
1791
+ "rows",
1792
+ "nodes"
1793
+ ];
1794
+ });
1795
+
1733
1796
  // .tmp-runtime-src/values/cache-key.ts
1734
1797
  function requestCacheKey(parts) {
1735
1798
  const method = (parts.method ?? "GET").toUpperCase();
@@ -2223,7 +2286,7 @@ var init_telemetry = __esm(() => {
2223
2286
  });
2224
2287
 
2225
2288
  // .tmp-runtime-src/build-info.generated.ts
2226
- var BUILD_RELEASE_VERSION = "9.5.0", BUILD_GIT_SHA = "e89197aa72c5", BUILD_CODE_HASH = "5d9ebf619c61", BUILD_RELEASE_MANIFEST_BASE64 = "eyJzY2hlbWFfdmVyc2lvbiI6MSwicmVsZWFzZV92ZXJzaW9uIjoiOS41LjAiLCJnaXRfc2hhIjoiZTg5MTk3YWE3MmM1IiwiY29kZV9oYXNoIjoiNWQ5ZWJmNjE5YzYxIiwidHJhY2VfdmVyc2lvbiI6IjVkOWViZjYxOWM2MUBlODkxOTdhYTcyYzUiLCJpc3N1ZWRfYXQiOiIyMDI2LTA2LTE3VDIwOjQzOjE0LjU3NVoifQ", BUILD_RELEASE_MANIFEST_SIGNATURE = "1UkHiCAP05Uq70_rXEXyo_0Z_VqVHG23WPNTxBlX5Fo", BUILD_DEFAULT_BACKEND_URL = "https://beta-api.unbrowse.ai", BUILD_DEFAULT_PROFILE = "";
2289
+ var BUILD_RELEASE_VERSION = "9.6.1", BUILD_GIT_SHA = "7c8049ccfb77", BUILD_CODE_HASH = "5d9ebf619c61", BUILD_RELEASE_MANIFEST_BASE64 = "eyJzY2hlbWFfdmVyc2lvbiI6MSwicmVsZWFzZV92ZXJzaW9uIjoiOS42LjEiLCJnaXRfc2hhIjoiN2M4MDQ5Y2NmYjc3IiwiY29kZV9oYXNoIjoiNWQ5ZWJmNjE5YzYxIiwidHJhY2VfdmVyc2lvbiI6IjVkOWViZjYxOWM2MUA3YzgwNDljY2ZiNzciLCJpc3N1ZWRfYXQiOiIyMDI2LTA2LTE4VDAzOjA1OjI0LjExOVoifQ", BUILD_RELEASE_MANIFEST_SIGNATURE = "EvwEtBNSpI-heDzj2LEUfGnS7PdM_EEZif1VhvQBaz8", BUILD_DEFAULT_BACKEND_URL = "https://beta-api.unbrowse.ai", BUILD_DEFAULT_PROFILE = "";
2227
2290
 
2228
2291
  // .tmp-runtime-src/version.ts
2229
2292
  import { createHash as createHash7 } from "crypto";
@@ -130488,6 +130551,69 @@ function bindingGraphFromOperationGraph(og) {
130488
130551
  return { endpoints, edges };
130489
130552
  }
130490
130553
 
130554
+ // .tmp-runtime-src/values/cardinality.ts
130555
+ function isListLikeIntent2(intent) {
130556
+ return LIST_INTENT_RE2.test(intent ?? "");
130557
+ }
130558
+ function schemaLooksLikeSingleItem(rs) {
130559
+ if (!rs || typeof rs !== "object")
130560
+ return false;
130561
+ const schema = rs;
130562
+ if (schema.type === "array")
130563
+ return false;
130564
+ const props = schema.properties ?? {};
130565
+ for (const key2 of COLLECTION_KEYS2) {
130566
+ if (key2 in props)
130567
+ return false;
130568
+ }
130569
+ for (const value of Object.values(props)) {
130570
+ if (value && typeof value === "object" && value.type === "array" && value.items?.type === "object") {
130571
+ return false;
130572
+ }
130573
+ }
130574
+ if (schema.type !== "object")
130575
+ return false;
130576
+ const hasType = "@type" in props;
130577
+ const hasName = "name" in props || "title" in props;
130578
+ const hasPriceish = "offers" in props || "price" in props || "sku" in props;
130579
+ return hasType || hasName && hasPriceish;
130580
+ }
130581
+ var LIST_INTENT_RE2, ITEM_SCHEMA_TYPES2, COLLECTION_KEYS2;
130582
+ var init_cardinality2 = __esm(() => {
130583
+ LIST_INTENT_RE2 = /\b(search|find|lookup|browse|discover|list(?:ings?)?|feed|catalog(?:ue)?)\b/i;
130584
+ ITEM_SCHEMA_TYPES2 = new Set([
130585
+ "product",
130586
+ "offer",
130587
+ "article",
130588
+ "newsarticle",
130589
+ "blogposting",
130590
+ "recipe",
130591
+ "event",
130592
+ "place",
130593
+ "localbusiness",
130594
+ "jobposting",
130595
+ "book",
130596
+ "movie",
130597
+ "creativework",
130598
+ "person",
130599
+ "organization"
130600
+ ]);
130601
+ COLLECTION_KEYS2 = [
130602
+ "itemListElement",
130603
+ "items",
130604
+ "results",
130605
+ "products",
130606
+ "listings",
130607
+ "data",
130608
+ "edges",
130609
+ "hits",
130610
+ "records",
130611
+ "entries",
130612
+ "rows",
130613
+ "nodes"
130614
+ ];
130615
+ });
130616
+
130491
130617
  // .tmp-runtime-src/values/yield-safety.ts
130492
130618
  function tokenizeKey(key2) {
130493
130619
  return key2.replace(/([a-z0-9])([A-Z])/g, "$1 $2").split(/[_\-.\s]+/).map((s) => s.toLowerCase()).filter(Boolean);
@@ -132128,6 +132254,38 @@ var init_mount = __esm(() => {
132128
132254
  import { existsSync as existsSync33, writeFileSync as writeFileSync20, readFileSync as readFileSync28, mkdirSync as mkdirSync22, readdirSync as readdirSync9 } from "node:fs";
132129
132255
  import { dirname as dirname7, join as join36 } from "node:path";
132130
132256
  import { createHash as createHash19 } from "node:crypto";
132257
+ function registrableHost(u) {
132258
+ if (!u)
132259
+ return null;
132260
+ try {
132261
+ return new URL(u).hostname.replace(/^www\./, "").split(".").slice(-2).join(".");
132262
+ } catch {
132263
+ return null;
132264
+ }
132265
+ }
132266
+ function shouldAutoWalk(requestedUrl, topUrl, topScore, minScore = 0.8) {
132267
+ if (!topUrl)
132268
+ return false;
132269
+ const reqReg = registrableHost(requestedUrl);
132270
+ const topReg = registrableHost(topUrl);
132271
+ return !!reqReg && reqReg === topReg || (topScore ?? 0) >= minScore;
132272
+ }
132273
+ function pickWalkTarget(requestedUrl, ranked, minScore = 0.8) {
132274
+ const eligible = ranked.filter((c) => c?.url && shouldAutoWalk(requestedUrl, c.url, c.score, minScore));
132275
+ if (eligible.length === 0)
132276
+ return null;
132277
+ const hasPath = (u) => {
132278
+ try {
132279
+ return new URL(u).pathname.replace(/\/+$/, "").length > 0;
132280
+ } catch {
132281
+ return false;
132282
+ }
132283
+ };
132284
+ const reqReg = registrableHost(requestedUrl);
132285
+ const sameDomain = reqReg ? eligible.filter((c) => registrableHost(c.url) === reqReg) : [];
132286
+ const pool2 = sameDomain.length > 0 ? sameDomain : eligible;
132287
+ return pool2.find((c) => hasPath(c.url)) ?? pool2[0];
132288
+ }
132131
132289
  function artifactResultWithShortlist(artifact, skillId, triggerUrl) {
132132
132290
  const ep = artifact.endpoint;
132133
132291
  const res = artifact.result;
@@ -132587,6 +132745,26 @@ function endpointTargetsMismatchedLocalReplayHost(endpoint, contextUrl) {
132587
132745
  function endpointHasNegativeTag(endpoint, tag) {
132588
132746
  return (endpoint.semantic?.negative_tags ?? []).some((candidate) => candidate.trim().toLowerCase() === tag.trim().toLowerCase());
132589
132747
  }
132748
+ function looksLikeSingleItemRoute(endpoint) {
132749
+ const tmpl = endpoint.url_template ?? "";
132750
+ let pathAndQuery = tmpl;
132751
+ try {
132752
+ const u = new URL(tmpl);
132753
+ pathAndQuery = `${u.pathname}${u.search}`;
132754
+ } catch {}
132755
+ const lower = pathAndQuery.toLowerCase();
132756
+ if (/\/(?:search|q|categories?|browse|results?|listings|explore|discover|feed|catalog(?:ue)?|collections?|shop|all)\b/.test(lower) || /[?&](?:q|query|keyword|keywords|search|term|category|cat|page)=/.test(lower)) {
132757
+ return false;
132758
+ }
132759
+ if (/\/(?:p|product|products|item|items|listing|detail|details|dp|pd|sku)\/[^/]+/.test(lower))
132760
+ return true;
132761
+ const lastSeg = lower.split("?")[0].replace(/\/+$/, "").split("/").pop() ?? "";
132762
+ if (/-\d{3,}$/.test(lastSeg) || /^\d{3,}$/.test(lastSeg))
132763
+ return true;
132764
+ if (/\{[^}]+\}/.test(lower))
132765
+ return false;
132766
+ return schemaLooksLikeSingleItem(endpoint.response_schema);
132767
+ }
132590
132768
  function isResolveUsableEndpointForIntent(endpoint, intent, contextUrl) {
132591
132769
  if (endpointTargetsMismatchedLocalReplayHost(endpoint, contextUrl))
132592
132770
  return false;
@@ -132596,6 +132774,9 @@ function isResolveUsableEndpointForIntent(endpoint, intent, contextUrl) {
132596
132774
  if (isFeedTimelineIntent(intent, contextUrl) && endpointHasNegativeTag(endpoint, "helper")) {
132597
132775
  return false;
132598
132776
  }
132777
+ if (isSearchLikeIntent(intent, contextUrl) && looksLikeSingleItemRoute(endpoint)) {
132778
+ return false;
132779
+ }
132599
132780
  return true;
132600
132781
  }
132601
132782
  function normalizeRouteContext(url) {
@@ -132667,6 +132848,19 @@ function promoteResultSnapshot(cacheKey2, skill, endpointId, result, trace) {
132667
132848
  expires: Date.now() + ROUTE_CACHE_TTL
132668
132849
  });
132669
132850
  }
132851
+ function persistWalkedRoute(scope, cacheKey2, walked) {
132852
+ try {
132853
+ const skill = walked.skill;
132854
+ if (!skill)
132855
+ return;
132856
+ const endpointId = walked.trace?.endpoint_id;
132857
+ const isReplayableRoute = (walked.source === "marketplace" || walked.source === "route-cache" || walked.source === "live-capture" || walked.source === "direct-fetch") && !!skill.endpoints?.length;
132858
+ if (isReplayableRoute) {
132859
+ promoteLearnedSkill(scope, cacheKey2, skill, endpointId, undefined);
132860
+ }
132861
+ promoteResultSnapshot(cacheKey2, skill, endpointId, walked.result, walked.trace);
132862
+ } catch {}
132863
+ }
132670
132864
  function buildCachedResultResponse(cached4, source, timing) {
132671
132865
  const now = new Date().toISOString();
132672
132866
  return {
@@ -132725,7 +132919,7 @@ function withContextReplayEndpoint(skill, _intent, _contextUrl) {
132725
132919
  return skill;
132726
132920
  }
132727
132921
  function isSearchLikeIntent(intent, contextUrl) {
132728
- if (/\b(search|find|lookup|browse|discover)\b/i.test(intent ?? ""))
132922
+ if (isListLikeIntent2(intent))
132729
132923
  return true;
132730
132924
  try {
132731
132925
  const pathname = contextUrl ? new URL(contextUrl).pathname.toLowerCase() : "";
@@ -133812,6 +134006,7 @@ function resolveEndpointTemplateBindings(endpoint, params = {}, contextUrl) {
133812
134006
  }
133813
134007
  async function resolveAndExecute(intent, params = {}, context, projection, options) {
133814
134008
  const t0 = Date.now();
134009
+ const walkDepth = options?.__walkDepth ?? 0;
133815
134010
  const timing = {
133816
134011
  search_ms: 0,
133817
134012
  get_skill_ms: 0,
@@ -135361,7 +135556,7 @@ async function resolveAndExecute(intent, params = {}, context, projection, optio
135361
135556
  }
135362
135557
  } catch {}
135363
135558
  }
135364
- if (exaHits.length > 0) {
135559
+ if (walkDepth === 0 && exaHits.length > 0) {
135365
135560
  const intentTokens = (queryIntent || "").toLowerCase().match(/[a-z0-9]{3,}/g) ?? [];
135366
135561
  const stop2 = new Set(["get", "the", "for", "from", "with", "and", "any", "all", "new", "top", "top1", "top10"]);
135367
135562
  const intentTokenSet = new Set(intentTokens.filter((t) => !stop2.has(t)));
@@ -135389,7 +135584,7 @@ async function resolveAndExecute(intent, params = {}, context, projection, optio
135389
135584
  console.log(`[exa] raw-candidate mode (UNBROWSE_EXA_RAW=1): keeping ${exaHits.length} low-score hits for the agent to judge`);
135390
135585
  }
135391
135586
  }
135392
- if (exaHits.length > 0) {
135587
+ if (walkDepth === 0 && exaHits.length > 0) {
135393
135588
  const richHit = pickAnswerHit(exaHits, raceProbeDomain);
135394
135589
  const candidates = exaHits.map((hit) => ({
135395
135590
  url: hit.url,
@@ -135422,6 +135617,40 @@ async function resolveAndExecute(intent, params = {}, context, projection, optio
135422
135617
  skill_id: "exa-web-search",
135423
135618
  domain: exaSkillDomain
135424
135619
  };
135620
+ const topWalk = pickWalkTarget(raceContextUrl, exaHits);
135621
+ if (topWalk?.url && walkDepth < 1) {
135622
+ try {
135623
+ const walked = await resolveAndExecute(intent, params, { url: topWalk.url, domain: registrableHost(topWalk.url) ?? undefined }, projection, { ...options ?? {}, __walkDepth: walkDepth + 1 });
135624
+ if (walked && walked.source !== "exa" && !walked.result?.exec_unsupported) {
135625
+ console.log(`[exa→walk] resolved candidate ${topWalk.url} via ${walked.source} (pointer pipe d${walkDepth + 1})`);
135626
+ {
135627
+ const wDom = context?.domain ?? (() => {
135628
+ try {
135629
+ return new URL(raceContextUrl).hostname;
135630
+ } catch {
135631
+ return null;
135632
+ }
135633
+ })();
135634
+ persistWalkedRoute(clientScope, scopedCacheKey(clientScope, buildResolveCacheKey(wDom ?? null, intent, raceContextUrl)), walked);
135635
+ }
135636
+ return {
135637
+ ...walked,
135638
+ result: {
135639
+ ...walked.result,
135640
+ walked_from: "exa-web-search",
135641
+ exa_candidates: candidates,
135642
+ run_plan: [
135643
+ { step: "resolve", mode: "web-search", status: "hit", label: "fallback", error: null, source: webProvider ?? "exa" },
135644
+ { step: "walk", mode: walked.source, status: "hit", label: "top-candidate", error: null, source: walked.source }
135645
+ ]
135646
+ }
135647
+ };
135648
+ }
135649
+ console.log(`[exa→walk] candidate ${topWalk.url} produced no ladder rung — candidate leaf`);
135650
+ } catch (e) {
135651
+ console.log(`[exa→walk] walk error (${e.message}) — candidate leaf`);
135652
+ }
135653
+ }
135425
135654
  return {
135426
135655
  result: {
135427
135656
  ...richHit ? {
@@ -136198,7 +136427,7 @@ async function resolveAndExecute(intent, params = {}, context, projection, optio
136198
136427
  console.log(`[ddg] $0 fallback failed: ${err.message}`);
136199
136428
  }
136200
136429
  }
136201
- if (viable.length === 0 && exaResults?.length) {
136430
+ if (walkDepth === 0 && viable.length === 0 && exaResults?.length) {
136202
136431
  const richHit = pickAnswerHit(exaResults, requestedDomain);
136203
136432
  if (richHit) {
136204
136433
  console.log(`[exa] returning highlights answer from ${richHit.url} (${(richHit.highlights ?? []).join(" ").length} chars) + ${exaResults.length} ranked candidate(s)`);
@@ -136221,6 +136450,31 @@ async function resolveAndExecute(intent, params = {}, context, projection, optio
136221
136450
  fetch: `unbrowse fetch --url ${JSON.stringify(hit.url)}`
136222
136451
  }
136223
136452
  }));
136453
+ const topWalk = pickWalkTarget(context?.url, exaResults);
136454
+ if (topWalk?.url && walkDepth < 1) {
136455
+ try {
136456
+ const walked = await resolveAndExecute(intent, params, { url: topWalk.url, domain: registrableHost(topWalk.url) ?? undefined }, projection, { ...options ?? {}, __walkDepth: walkDepth + 1 });
136457
+ if (walked && walked.source !== "exa" && !walked.result?.exec_unsupported) {
136458
+ console.log(`[exa→walk] resolved candidate ${topWalk.url} via ${walked.source} (pointer pipe d${walkDepth + 1})`);
136459
+ persistWalkedRoute(clientScope, cacheKey2, walked);
136460
+ return {
136461
+ ...walked,
136462
+ result: {
136463
+ ...walked.result,
136464
+ walked_from: "exa-web-search",
136465
+ exa_candidates: candidates2,
136466
+ run_plan: [
136467
+ { step: "resolve", mode: "web-search", status: "hit", label: "fallback", error: null, source: serialWebProvider ?? "exa" },
136468
+ { step: "walk", mode: walked.source, status: "hit", label: "top-candidate", error: null, source: walked.source }
136469
+ ]
136470
+ }
136471
+ };
136472
+ }
136473
+ console.log(`[exa→walk] candidate ${topWalk.url} produced no ladder rung — exa leaf`);
136474
+ } catch (e) {
136475
+ console.log(`[exa→walk] walk error (${e.message}) — exa leaf`);
136476
+ }
136477
+ }
136224
136478
  return {
136225
136479
  result: {
136226
136480
  data: richHit.highlights,
@@ -137379,6 +137633,8 @@ var init_orchestrator = __esm(async () => {
137379
137633
  init_search_forms();
137380
137634
  init_ddg_search();
137381
137635
  init_cached_resolution2();
137636
+ init_cardinality2();
137637
+ init_cardinality2();
137382
137638
  init_principal_scope();
137383
137639
  init_yield_safety();
137384
137640
  init_trace_store();
@@ -239259,7 +239515,7 @@ async function cmdResolve(flags) {
239259
239515
  }
239260
239516
  if (resolveCacheSafe(flags)) {
239261
239517
  const cachedHit = peekResolution(resolveCacheKeyFor(flags, intent), resolveCacheTtlMs());
239262
- if (cachedHit) {
239518
+ if (cachedHit && resolutionCardinalityMatches(intent, cachedHit.result ?? cachedHit.data)) {
239263
239519
  const replay = markResolveCacheReplay(cachedHit);
239264
239520
  const hostType2 = detectTelemetryHostType2();
239265
239521
  if (process.env.UNBROWSE_LANDING_TOKEN || process.env.UNBROWSE_ATTRIBUTION_B64) {
@@ -239479,7 +239735,7 @@ async function cmdResolve(flags) {
239479
239735
  if (skill?.skill_id && trace) {
239480
239736
  result._feedback = `unbrowse feedback --skill ${skill.skill_id} --endpoint ${trace.endpoint_id || "?"} --rating <1-5>`;
239481
239737
  }
239482
- if (resolveCacheSafe(flags) && isResolveSuccessResult(result)) {
239738
+ if (resolveCacheSafe(flags) && isResolveSuccessResult(result) && resolutionCardinalityMatches(intent, result.result ?? result.data)) {
239483
239739
  storeResolution(resolveCacheKeyFor(flags, intent), result, resolveCacheTtlMs());
239484
239740
  }
239485
239741
  output(result, !!flags.pretty);
@@ -241610,6 +241866,7 @@ var init_cli = __esm(async () => {
241610
241866
  init_extract_auth_header();
241611
241867
  init_kuri_proxy_bridge();
241612
241868
  init_cached_resolution();
241869
+ init_cardinality();
241613
241870
  init_issue();
241614
241871
  init_client2();
241615
241872
  init_impact_log();
package/runtime/mcp.js CHANGED
@@ -36310,7 +36310,7 @@ var init_cached_resolution = __esm(() => {
36310
36310
  });
36311
36311
 
36312
36312
  // .tmp-runtime-src/build-info.generated.ts
36313
- var BUILD_RELEASE_VERSION = "9.5.0", BUILD_GIT_SHA = "e89197aa72c5", BUILD_CODE_HASH = "5d9ebf619c61", BUILD_RELEASE_MANIFEST_BASE64 = "eyJzY2hlbWFfdmVyc2lvbiI6MSwicmVsZWFzZV92ZXJzaW9uIjoiOS41LjAiLCJnaXRfc2hhIjoiZTg5MTk3YWE3MmM1IiwiY29kZV9oYXNoIjoiNWQ5ZWJmNjE5YzYxIiwidHJhY2VfdmVyc2lvbiI6IjVkOWViZjYxOWM2MUBlODkxOTdhYTcyYzUiLCJpc3N1ZWRfYXQiOiIyMDI2LTA2LTE3VDIwOjQzOjE0LjU3NVoifQ", BUILD_RELEASE_MANIFEST_SIGNATURE = "1UkHiCAP05Uq70_rXEXyo_0Z_VqVHG23WPNTxBlX5Fo", BUILD_DEFAULT_BACKEND_URL = "https://beta-api.unbrowse.ai", BUILD_DEFAULT_PROFILE = "";
36313
+ var BUILD_RELEASE_VERSION = "9.6.1", BUILD_GIT_SHA = "7c8049ccfb77", BUILD_CODE_HASH = "5d9ebf619c61", BUILD_RELEASE_MANIFEST_BASE64 = "eyJzY2hlbWFfdmVyc2lvbiI6MSwicmVsZWFzZV92ZXJzaW9uIjoiOS42LjEiLCJnaXRfc2hhIjoiN2M4MDQ5Y2NmYjc3IiwiY29kZV9oYXNoIjoiNWQ5ZWJmNjE5YzYxIiwidHJhY2VfdmVyc2lvbiI6IjVkOWViZjYxOWM2MUA3YzgwNDljY2ZiNzciLCJpc3N1ZWRfYXQiOiIyMDI2LTA2LTE4VDAzOjA1OjI0LjExOVoifQ", BUILD_RELEASE_MANIFEST_SIGNATURE = "EvwEtBNSpI-heDzj2LEUfGnS7PdM_EEZif1VhvQBaz8", BUILD_DEFAULT_BACKEND_URL = "https://beta-api.unbrowse.ai", BUILD_DEFAULT_PROFILE = "";
36314
36314
 
36315
36315
  // .tmp-runtime-src/version.ts
36316
36316
  import { createHash as createHash4 } from "crypto";
@@ -128876,6 +128876,92 @@ function bindingGraphFromOperationGraph(og) {
128876
128876
  return { endpoints, edges };
128877
128877
  }
128878
128878
 
128879
+ // .tmp-runtime-src/values/cardinality.ts
128880
+ function isListLikeIntent(intent) {
128881
+ return LIST_INTENT_RE.test(intent ?? "");
128882
+ }
128883
+ function valueLooksLikeSingleItem(value) {
128884
+ if (value == null || Array.isArray(value) || typeof value !== "object")
128885
+ return false;
128886
+ const obj = value;
128887
+ for (const key2 of COLLECTION_KEYS) {
128888
+ if (Array.isArray(obj[key2]))
128889
+ return false;
128890
+ }
128891
+ for (const v of Object.values(obj)) {
128892
+ if (Array.isArray(v) && v.some((x) => x !== null && typeof x === "object"))
128893
+ return false;
128894
+ }
128895
+ const atType = typeof obj["@type"] === "string" ? obj["@type"].toLowerCase() : "";
128896
+ const isItemType = ITEM_SCHEMA_TYPES.has(atType);
128897
+ const hasName = "name" in obj || "title" in obj || "headline" in obj;
128898
+ const hasPriceish = "offers" in obj || "price" in obj || "sku" in obj;
128899
+ return isItemType || hasName && hasPriceish;
128900
+ }
128901
+ function schemaLooksLikeSingleItem(rs) {
128902
+ if (!rs || typeof rs !== "object")
128903
+ return false;
128904
+ const schema = rs;
128905
+ if (schema.type === "array")
128906
+ return false;
128907
+ const props = schema.properties ?? {};
128908
+ for (const key2 of COLLECTION_KEYS) {
128909
+ if (key2 in props)
128910
+ return false;
128911
+ }
128912
+ for (const value of Object.values(props)) {
128913
+ if (value && typeof value === "object" && value.type === "array" && value.items?.type === "object") {
128914
+ return false;
128915
+ }
128916
+ }
128917
+ if (schema.type !== "object")
128918
+ return false;
128919
+ const hasType = "@type" in props;
128920
+ const hasName = "name" in props || "title" in props;
128921
+ const hasPriceish = "offers" in props || "price" in props || "sku" in props;
128922
+ return hasType || hasName && hasPriceish;
128923
+ }
128924
+ function resolutionCardinalityMatches(intent, data2) {
128925
+ if (!isListLikeIntent(intent))
128926
+ return true;
128927
+ return !valueLooksLikeSingleItem(data2);
128928
+ }
128929
+ var LIST_INTENT_RE, ITEM_SCHEMA_TYPES, COLLECTION_KEYS;
128930
+ var init_cardinality = __esm(() => {
128931
+ LIST_INTENT_RE = /\b(search|find|lookup|browse|discover|list(?:ings?)?|feed|catalog(?:ue)?)\b/i;
128932
+ ITEM_SCHEMA_TYPES = new Set([
128933
+ "product",
128934
+ "offer",
128935
+ "article",
128936
+ "newsarticle",
128937
+ "blogposting",
128938
+ "recipe",
128939
+ "event",
128940
+ "place",
128941
+ "localbusiness",
128942
+ "jobposting",
128943
+ "book",
128944
+ "movie",
128945
+ "creativework",
128946
+ "person",
128947
+ "organization"
128948
+ ]);
128949
+ COLLECTION_KEYS = [
128950
+ "itemListElement",
128951
+ "items",
128952
+ "results",
128953
+ "products",
128954
+ "listings",
128955
+ "data",
128956
+ "edges",
128957
+ "hits",
128958
+ "records",
128959
+ "entries",
128960
+ "rows",
128961
+ "nodes"
128962
+ ];
128963
+ });
128964
+
128879
128965
  // .tmp-runtime-src/values/yield-safety.ts
128880
128966
  function tokenizeKey(key2) {
128881
128967
  return key2.replace(/([a-z0-9])([A-Z])/g, "$1 $2").split(/[_\-.\s]+/).map((s) => s.toLowerCase()).filter(Boolean);
@@ -130540,6 +130626,38 @@ var init_mount = __esm(() => {
130540
130626
  import { existsSync as existsSync27, writeFileSync as writeFileSync17, readFileSync as readFileSync23, mkdirSync as mkdirSync19, readdirSync as readdirSync8 } from "node:fs";
130541
130627
  import { dirname as dirname6, join as join33 } from "node:path";
130542
130628
  import { createHash as createHash14 } from "node:crypto";
130629
+ function registrableHost(u) {
130630
+ if (!u)
130631
+ return null;
130632
+ try {
130633
+ return new URL(u).hostname.replace(/^www\./, "").split(".").slice(-2).join(".");
130634
+ } catch {
130635
+ return null;
130636
+ }
130637
+ }
130638
+ function shouldAutoWalk(requestedUrl, topUrl, topScore, minScore = 0.8) {
130639
+ if (!topUrl)
130640
+ return false;
130641
+ const reqReg = registrableHost(requestedUrl);
130642
+ const topReg = registrableHost(topUrl);
130643
+ return !!reqReg && reqReg === topReg || (topScore ?? 0) >= minScore;
130644
+ }
130645
+ function pickWalkTarget(requestedUrl, ranked, minScore = 0.8) {
130646
+ const eligible = ranked.filter((c) => c?.url && shouldAutoWalk(requestedUrl, c.url, c.score, minScore));
130647
+ if (eligible.length === 0)
130648
+ return null;
130649
+ const hasPath = (u) => {
130650
+ try {
130651
+ return new URL(u).pathname.replace(/\/+$/, "").length > 0;
130652
+ } catch {
130653
+ return false;
130654
+ }
130655
+ };
130656
+ const reqReg = registrableHost(requestedUrl);
130657
+ const sameDomain = reqReg ? eligible.filter((c) => registrableHost(c.url) === reqReg) : [];
130658
+ const pool2 = sameDomain.length > 0 ? sameDomain : eligible;
130659
+ return pool2.find((c) => hasPath(c.url)) ?? pool2[0];
130660
+ }
130543
130661
  function artifactResultWithShortlist(artifact, skillId, triggerUrl) {
130544
130662
  const ep = artifact.endpoint;
130545
130663
  const res = artifact.result;
@@ -130999,6 +131117,26 @@ function endpointTargetsMismatchedLocalReplayHost(endpoint, contextUrl) {
130999
131117
  function endpointHasNegativeTag(endpoint, tag) {
131000
131118
  return (endpoint.semantic?.negative_tags ?? []).some((candidate) => candidate.trim().toLowerCase() === tag.trim().toLowerCase());
131001
131119
  }
131120
+ function looksLikeSingleItemRoute(endpoint) {
131121
+ const tmpl = endpoint.url_template ?? "";
131122
+ let pathAndQuery = tmpl;
131123
+ try {
131124
+ const u = new URL(tmpl);
131125
+ pathAndQuery = `${u.pathname}${u.search}`;
131126
+ } catch {}
131127
+ const lower = pathAndQuery.toLowerCase();
131128
+ if (/\/(?:search|q|categories?|browse|results?|listings|explore|discover|feed|catalog(?:ue)?|collections?|shop|all)\b/.test(lower) || /[?&](?:q|query|keyword|keywords|search|term|category|cat|page)=/.test(lower)) {
131129
+ return false;
131130
+ }
131131
+ if (/\/(?:p|product|products|item|items|listing|detail|details|dp|pd|sku)\/[^/]+/.test(lower))
131132
+ return true;
131133
+ const lastSeg = lower.split("?")[0].replace(/\/+$/, "").split("/").pop() ?? "";
131134
+ if (/-\d{3,}$/.test(lastSeg) || /^\d{3,}$/.test(lastSeg))
131135
+ return true;
131136
+ if (/\{[^}]+\}/.test(lower))
131137
+ return false;
131138
+ return schemaLooksLikeSingleItem(endpoint.response_schema);
131139
+ }
131002
131140
  function isResolveUsableEndpointForIntent(endpoint, intent, contextUrl) {
131003
131141
  if (endpointTargetsMismatchedLocalReplayHost(endpoint, contextUrl))
131004
131142
  return false;
@@ -131008,6 +131146,9 @@ function isResolveUsableEndpointForIntent(endpoint, intent, contextUrl) {
131008
131146
  if (isFeedTimelineIntent(intent, contextUrl) && endpointHasNegativeTag(endpoint, "helper")) {
131009
131147
  return false;
131010
131148
  }
131149
+ if (isSearchLikeIntent(intent, contextUrl) && looksLikeSingleItemRoute(endpoint)) {
131150
+ return false;
131151
+ }
131011
131152
  return true;
131012
131153
  }
131013
131154
  function normalizeRouteContext(url) {
@@ -131079,6 +131220,19 @@ function promoteResultSnapshot(cacheKey2, skill, endpointId, result, trace) {
131079
131220
  expires: Date.now() + ROUTE_CACHE_TTL
131080
131221
  });
131081
131222
  }
131223
+ function persistWalkedRoute(scope, cacheKey2, walked) {
131224
+ try {
131225
+ const skill = walked.skill;
131226
+ if (!skill)
131227
+ return;
131228
+ const endpointId = walked.trace?.endpoint_id;
131229
+ const isReplayableRoute = (walked.source === "marketplace" || walked.source === "route-cache" || walked.source === "live-capture" || walked.source === "direct-fetch") && !!skill.endpoints?.length;
131230
+ if (isReplayableRoute) {
131231
+ promoteLearnedSkill(scope, cacheKey2, skill, endpointId, undefined);
131232
+ }
131233
+ promoteResultSnapshot(cacheKey2, skill, endpointId, walked.result, walked.trace);
131234
+ } catch {}
131235
+ }
131082
131236
  function buildCachedResultResponse(cached4, source, timing) {
131083
131237
  const now = new Date().toISOString();
131084
131238
  return {
@@ -131137,7 +131291,7 @@ function withContextReplayEndpoint(skill, _intent, _contextUrl) {
131137
131291
  return skill;
131138
131292
  }
131139
131293
  function isSearchLikeIntent(intent, contextUrl) {
131140
- if (/\b(search|find|lookup|browse|discover)\b/i.test(intent ?? ""))
131294
+ if (isListLikeIntent(intent))
131141
131295
  return true;
131142
131296
  try {
131143
131297
  const pathname = contextUrl ? new URL(contextUrl).pathname.toLowerCase() : "";
@@ -132224,6 +132378,7 @@ function resolveEndpointTemplateBindings(endpoint, params = {}, contextUrl) {
132224
132378
  }
132225
132379
  async function resolveAndExecute(intent, params = {}, context, projection, options) {
132226
132380
  const t0 = Date.now();
132381
+ const walkDepth = options?.__walkDepth ?? 0;
132227
132382
  const timing = {
132228
132383
  search_ms: 0,
132229
132384
  get_skill_ms: 0,
@@ -133773,7 +133928,7 @@ async function resolveAndExecute(intent, params = {}, context, projection, optio
133773
133928
  }
133774
133929
  } catch {}
133775
133930
  }
133776
- if (exaHits.length > 0) {
133931
+ if (walkDepth === 0 && exaHits.length > 0) {
133777
133932
  const intentTokens = (queryIntent || "").toLowerCase().match(/[a-z0-9]{3,}/g) ?? [];
133778
133933
  const stop2 = new Set(["get", "the", "for", "from", "with", "and", "any", "all", "new", "top", "top1", "top10"]);
133779
133934
  const intentTokenSet = new Set(intentTokens.filter((t) => !stop2.has(t)));
@@ -133801,7 +133956,7 @@ async function resolveAndExecute(intent, params = {}, context, projection, optio
133801
133956
  console.log(`[exa] raw-candidate mode (UNBROWSE_EXA_RAW=1): keeping ${exaHits.length} low-score hits for the agent to judge`);
133802
133957
  }
133803
133958
  }
133804
- if (exaHits.length > 0) {
133959
+ if (walkDepth === 0 && exaHits.length > 0) {
133805
133960
  const richHit = pickAnswerHit(exaHits, raceProbeDomain);
133806
133961
  const candidates = exaHits.map((hit) => ({
133807
133962
  url: hit.url,
@@ -133834,6 +133989,40 @@ async function resolveAndExecute(intent, params = {}, context, projection, optio
133834
133989
  skill_id: "exa-web-search",
133835
133990
  domain: exaSkillDomain
133836
133991
  };
133992
+ const topWalk = pickWalkTarget(raceContextUrl, exaHits);
133993
+ if (topWalk?.url && walkDepth < 1) {
133994
+ try {
133995
+ const walked = await resolveAndExecute(intent, params, { url: topWalk.url, domain: registrableHost(topWalk.url) ?? undefined }, projection, { ...options ?? {}, __walkDepth: walkDepth + 1 });
133996
+ if (walked && walked.source !== "exa" && !walked.result?.exec_unsupported) {
133997
+ console.log(`[exa→walk] resolved candidate ${topWalk.url} via ${walked.source} (pointer pipe d${walkDepth + 1})`);
133998
+ {
133999
+ const wDom = context?.domain ?? (() => {
134000
+ try {
134001
+ return new URL(raceContextUrl).hostname;
134002
+ } catch {
134003
+ return null;
134004
+ }
134005
+ })();
134006
+ persistWalkedRoute(clientScope, scopedCacheKey(clientScope, buildResolveCacheKey(wDom ?? null, intent, raceContextUrl)), walked);
134007
+ }
134008
+ return {
134009
+ ...walked,
134010
+ result: {
134011
+ ...walked.result,
134012
+ walked_from: "exa-web-search",
134013
+ exa_candidates: candidates,
134014
+ run_plan: [
134015
+ { step: "resolve", mode: "web-search", status: "hit", label: "fallback", error: null, source: webProvider ?? "exa" },
134016
+ { step: "walk", mode: walked.source, status: "hit", label: "top-candidate", error: null, source: walked.source }
134017
+ ]
134018
+ }
134019
+ };
134020
+ }
134021
+ console.log(`[exa→walk] candidate ${topWalk.url} produced no ladder rung — candidate leaf`);
134022
+ } catch (e) {
134023
+ console.log(`[exa→walk] walk error (${e.message}) — candidate leaf`);
134024
+ }
134025
+ }
133837
134026
  return {
133838
134027
  result: {
133839
134028
  ...richHit ? {
@@ -134610,7 +134799,7 @@ async function resolveAndExecute(intent, params = {}, context, projection, optio
134610
134799
  console.log(`[ddg] $0 fallback failed: ${err.message}`);
134611
134800
  }
134612
134801
  }
134613
- if (viable.length === 0 && exaResults?.length) {
134802
+ if (walkDepth === 0 && viable.length === 0 && exaResults?.length) {
134614
134803
  const richHit = pickAnswerHit(exaResults, requestedDomain);
134615
134804
  if (richHit) {
134616
134805
  console.log(`[exa] returning highlights answer from ${richHit.url} (${(richHit.highlights ?? []).join(" ").length} chars) + ${exaResults.length} ranked candidate(s)`);
@@ -134633,6 +134822,31 @@ async function resolveAndExecute(intent, params = {}, context, projection, optio
134633
134822
  fetch: `unbrowse fetch --url ${JSON.stringify(hit.url)}`
134634
134823
  }
134635
134824
  }));
134825
+ const topWalk = pickWalkTarget(context?.url, exaResults);
134826
+ if (topWalk?.url && walkDepth < 1) {
134827
+ try {
134828
+ const walked = await resolveAndExecute(intent, params, { url: topWalk.url, domain: registrableHost(topWalk.url) ?? undefined }, projection, { ...options ?? {}, __walkDepth: walkDepth + 1 });
134829
+ if (walked && walked.source !== "exa" && !walked.result?.exec_unsupported) {
134830
+ console.log(`[exa→walk] resolved candidate ${topWalk.url} via ${walked.source} (pointer pipe d${walkDepth + 1})`);
134831
+ persistWalkedRoute(clientScope, cacheKey2, walked);
134832
+ return {
134833
+ ...walked,
134834
+ result: {
134835
+ ...walked.result,
134836
+ walked_from: "exa-web-search",
134837
+ exa_candidates: candidates2,
134838
+ run_plan: [
134839
+ { step: "resolve", mode: "web-search", status: "hit", label: "fallback", error: null, source: serialWebProvider ?? "exa" },
134840
+ { step: "walk", mode: walked.source, status: "hit", label: "top-candidate", error: null, source: walked.source }
134841
+ ]
134842
+ }
134843
+ };
134844
+ }
134845
+ console.log(`[exa→walk] candidate ${topWalk.url} produced no ladder rung — exa leaf`);
134846
+ } catch (e) {
134847
+ console.log(`[exa→walk] walk error (${e.message}) — exa leaf`);
134848
+ }
134849
+ }
134636
134850
  return {
134637
134851
  result: {
134638
134852
  data: richHit.highlights,
@@ -135791,6 +136005,8 @@ var init_orchestrator = __esm(async () => {
135791
136005
  init_search_forms();
135792
136006
  init_ddg_search();
135793
136007
  init_cached_resolution();
136008
+ init_cardinality();
136009
+ init_cardinality();
135794
136010
  init_principal_scope();
135795
136011
  init_yield_safety();
135796
136012
  init_trace_store();
@@ -232477,7 +232693,7 @@ async function cmdResolve(flags) {
232477
232693
  }
232478
232694
  if (resolveCacheSafe(flags)) {
232479
232695
  const cachedHit = peekResolution(resolveCacheKeyFor(flags, intent), resolveCacheTtlMs());
232480
- if (cachedHit) {
232696
+ if (cachedHit && resolutionCardinalityMatches(intent, cachedHit.result ?? cachedHit.data)) {
232481
232697
  const replay = markResolveCacheReplay(cachedHit);
232482
232698
  const hostType2 = detectTelemetryHostType();
232483
232699
  if (process.env.UNBROWSE_LANDING_TOKEN || process.env.UNBROWSE_ATTRIBUTION_B64) {
@@ -232697,7 +232913,7 @@ async function cmdResolve(flags) {
232697
232913
  if (skill?.skill_id && trace) {
232698
232914
  result._feedback = `unbrowse feedback --skill ${skill.skill_id} --endpoint ${trace.endpoint_id || "?"} --rating <1-5>`;
232699
232915
  }
232700
- if (resolveCacheSafe(flags) && isResolveSuccessResult(result)) {
232916
+ if (resolveCacheSafe(flags) && isResolveSuccessResult(result) && resolutionCardinalityMatches(intent, result.result ?? result.data)) {
232701
232917
  storeResolution(resolveCacheKeyFor(flags, intent), result, resolveCacheTtlMs());
232702
232918
  }
232703
232919
  output(result, !!flags.pretty);
@@ -234814,6 +235030,7 @@ var init_cli = __esm(async () => {
234814
235030
  init_extract_auth_header();
234815
235031
  init_kuri_proxy_bridge();
234816
235032
  init_cached_resolution();
235033
+ init_cardinality();
234817
235034
  init_issue();
234818
235035
  init_client2();
234819
235036
  init_impact_log();
@@ -236100,11 +236317,14 @@ __export(exports_orchestrator, {
236100
236317
  shouldReuseRouteResultSnapshot: () => shouldReuseRouteResultSnapshot2,
236101
236318
  shouldFallbackToLiveCaptureAfterAutoexecFailure: () => shouldFallbackToLiveCaptureAfterAutoexecFailure2,
236102
236319
  shouldBypassLiveCaptureQueue: () => shouldBypassLiveCaptureQueue2,
236320
+ shouldAutoWalk: () => shouldAutoWalk2,
236103
236321
  selectSkillIdsToHydrate: () => selectSkillIdsToHydrate2,
236104
236322
  selectSearchTermsForExecution: () => selectSearchTermsForExecution2,
236105
236323
  scopedCacheKey: () => scopedCacheKey2,
236324
+ schemaLooksLikeSingleItem: () => schemaLooksLikeSingleItem,
236106
236325
  resolveEndpointTemplateBindings: () => resolveEndpointTemplateBindings2,
236107
236326
  resolveAndExecute: () => resolveAndExecute2,
236327
+ registrableHost: () => registrableHost2,
236108
236328
  readSkillSnapshot: () => readSkillSnapshot2,
236109
236329
  readComposite: () => readComposite2,
236110
236330
  pruneLocalCacheEntriesForSkill: () => pruneLocalCacheEntriesForSkill2,
@@ -236112,10 +236332,13 @@ __export(exports_orchestrator, {
236112
236332
  probeLooksLikeFetchableHtmlDocument: () => probeLooksLikeFetchableHtmlDocument2,
236113
236333
  probeLooksLikeDirectJsonApi: () => probeLooksLikeDirectJsonApi2,
236114
236334
  planPrereqOrder: () => planPrereqOrder2,
236335
+ pickWalkTarget: () => pickWalkTarget2,
236115
236336
  pickPreferredSkillSnapshot: () => pickPreferredSkillSnapshot2,
236116
236337
  persistDomainCache: () => persistDomainCache2,
236117
236338
  marketplaceSkillMatchesContext: () => marketplaceSkillMatchesContext2,
236339
+ looksLikeSingleItemRoute: () => looksLikeSingleItemRoute2,
236118
236340
  isRouteCacheEntryStale: () => isRouteCacheEntryStale2,
236341
+ isResolveUsableEndpointForIntent: () => isResolveUsableEndpointForIntent2,
236119
236342
  isCachedSkillRelevantForIntent: () => isCachedSkillRelevantForIntent2,
236120
236343
  invalidateRouteCacheForDomain: () => invalidateRouteCacheForDomain3,
236121
236344
  inferSearchParamOverrides: () => inferSearchParamOverrides2,
@@ -236143,6 +236366,38 @@ __export(exports_orchestrator, {
236143
236366
  import { existsSync as existsSync60, writeFileSync as writeFileSync35, readFileSync as readFileSync49, mkdirSync as mkdirSync39, readdirSync as readdirSync17 } from "node:fs";
236144
236367
  import { dirname as dirname15, join as join68 } from "node:path";
236145
236368
  import { createHash as createHash48 } from "node:crypto";
236369
+ function registrableHost2(u) {
236370
+ if (!u)
236371
+ return null;
236372
+ try {
236373
+ return new URL(u).hostname.replace(/^www\./, "").split(".").slice(-2).join(".");
236374
+ } catch {
236375
+ return null;
236376
+ }
236377
+ }
236378
+ function shouldAutoWalk2(requestedUrl, topUrl, topScore, minScore = 0.8) {
236379
+ if (!topUrl)
236380
+ return false;
236381
+ const reqReg = registrableHost2(requestedUrl);
236382
+ const topReg = registrableHost2(topUrl);
236383
+ return !!reqReg && reqReg === topReg || (topScore ?? 0) >= minScore;
236384
+ }
236385
+ function pickWalkTarget2(requestedUrl, ranked, minScore = 0.8) {
236386
+ const eligible = ranked.filter((c) => c?.url && shouldAutoWalk2(requestedUrl, c.url, c.score, minScore));
236387
+ if (eligible.length === 0)
236388
+ return null;
236389
+ const hasPath = (u) => {
236390
+ try {
236391
+ return new URL(u).pathname.replace(/\/+$/, "").length > 0;
236392
+ } catch {
236393
+ return false;
236394
+ }
236395
+ };
236396
+ const reqReg = registrableHost2(requestedUrl);
236397
+ const sameDomain = reqReg ? eligible.filter((c) => registrableHost2(c.url) === reqReg) : [];
236398
+ const pool2 = sameDomain.length > 0 ? sameDomain : eligible;
236399
+ return pool2.find((c) => hasPath(c.url)) ?? pool2[0];
236400
+ }
236146
236401
  function artifactResultWithShortlist2(artifact, skillId, triggerUrl) {
236147
236402
  const ep = artifact.endpoint;
236148
236403
  const res = artifact.result;
@@ -236602,6 +236857,26 @@ function endpointTargetsMismatchedLocalReplayHost2(endpoint, contextUrl) {
236602
236857
  function endpointHasNegativeTag2(endpoint, tag) {
236603
236858
  return (endpoint.semantic?.negative_tags ?? []).some((candidate) => candidate.trim().toLowerCase() === tag.trim().toLowerCase());
236604
236859
  }
236860
+ function looksLikeSingleItemRoute2(endpoint) {
236861
+ const tmpl = endpoint.url_template ?? "";
236862
+ let pathAndQuery = tmpl;
236863
+ try {
236864
+ const u = new URL(tmpl);
236865
+ pathAndQuery = `${u.pathname}${u.search}`;
236866
+ } catch {}
236867
+ const lower = pathAndQuery.toLowerCase();
236868
+ if (/\/(?:search|q|categories?|browse|results?|listings|explore|discover|feed|catalog(?:ue)?|collections?|shop|all)\b/.test(lower) || /[?&](?:q|query|keyword|keywords|search|term|category|cat|page)=/.test(lower)) {
236869
+ return false;
236870
+ }
236871
+ if (/\/(?:p|product|products|item|items|listing|detail|details|dp|pd|sku)\/[^/]+/.test(lower))
236872
+ return true;
236873
+ const lastSeg = lower.split("?")[0].replace(/\/+$/, "").split("/").pop() ?? "";
236874
+ if (/-\d{3,}$/.test(lastSeg) || /^\d{3,}$/.test(lastSeg))
236875
+ return true;
236876
+ if (/\{[^}]+\}/.test(lower))
236877
+ return false;
236878
+ return schemaLooksLikeSingleItem(endpoint.response_schema);
236879
+ }
236605
236880
  function isResolveUsableEndpointForIntent2(endpoint, intent, contextUrl) {
236606
236881
  if (endpointTargetsMismatchedLocalReplayHost2(endpoint, contextUrl))
236607
236882
  return false;
@@ -236611,6 +236886,9 @@ function isResolveUsableEndpointForIntent2(endpoint, intent, contextUrl) {
236611
236886
  if (isFeedTimelineIntent2(intent, contextUrl) && endpointHasNegativeTag2(endpoint, "helper")) {
236612
236887
  return false;
236613
236888
  }
236889
+ if (isSearchLikeIntent2(intent, contextUrl) && looksLikeSingleItemRoute2(endpoint)) {
236890
+ return false;
236891
+ }
236614
236892
  return true;
236615
236893
  }
236616
236894
  function normalizeRouteContext2(url) {
@@ -236682,6 +236960,19 @@ function promoteResultSnapshot2(cacheKey2, skill, endpointId, result, trace) {
236682
236960
  expires: Date.now() + ROUTE_CACHE_TTL2
236683
236961
  });
236684
236962
  }
236963
+ function persistWalkedRoute2(scope, cacheKey2, walked) {
236964
+ try {
236965
+ const skill = walked.skill;
236966
+ if (!skill)
236967
+ return;
236968
+ const endpointId = walked.trace?.endpoint_id;
236969
+ const isReplayableRoute = (walked.source === "marketplace" || walked.source === "route-cache" || walked.source === "live-capture" || walked.source === "direct-fetch") && !!skill.endpoints?.length;
236970
+ if (isReplayableRoute) {
236971
+ promoteLearnedSkill2(scope, cacheKey2, skill, endpointId, undefined);
236972
+ }
236973
+ promoteResultSnapshot2(cacheKey2, skill, endpointId, walked.result, walked.trace);
236974
+ } catch {}
236975
+ }
236685
236976
  function buildCachedResultResponse2(cached5, source, timing) {
236686
236977
  const now = new Date().toISOString();
236687
236978
  return {
@@ -236740,7 +237031,7 @@ function withContextReplayEndpoint2(skill, _intent, _contextUrl) {
236740
237031
  return skill;
236741
237032
  }
236742
237033
  function isSearchLikeIntent2(intent, contextUrl) {
236743
- if (/\b(search|find|lookup|browse|discover)\b/i.test(intent ?? ""))
237034
+ if (isListLikeIntent(intent))
236744
237035
  return true;
236745
237036
  try {
236746
237037
  const pathname = contextUrl ? new URL(contextUrl).pathname.toLowerCase() : "";
@@ -237832,6 +238123,7 @@ function resolveEndpointTemplateBindings2(endpoint, params = {}, contextUrl) {
237832
238123
  }
237833
238124
  async function resolveAndExecute2(intent, params = {}, context, projection, options) {
237834
238125
  const t0 = Date.now();
238126
+ const walkDepth = options?.__walkDepth ?? 0;
237835
238127
  const timing = {
237836
238128
  search_ms: 0,
237837
238129
  get_skill_ms: 0,
@@ -239381,7 +239673,7 @@ async function resolveAndExecute2(intent, params = {}, context, projection, opti
239381
239673
  }
239382
239674
  } catch {}
239383
239675
  }
239384
- if (exaHits.length > 0) {
239676
+ if (walkDepth === 0 && exaHits.length > 0) {
239385
239677
  const intentTokens = (queryIntent || "").toLowerCase().match(/[a-z0-9]{3,}/g) ?? [];
239386
239678
  const stop2 = new Set(["get", "the", "for", "from", "with", "and", "any", "all", "new", "top", "top1", "top10"]);
239387
239679
  const intentTokenSet = new Set(intentTokens.filter((t) => !stop2.has(t)));
@@ -239409,7 +239701,7 @@ async function resolveAndExecute2(intent, params = {}, context, projection, opti
239409
239701
  console.log(`[exa] raw-candidate mode (UNBROWSE_EXA_RAW=1): keeping ${exaHits.length} low-score hits for the agent to judge`);
239410
239702
  }
239411
239703
  }
239412
- if (exaHits.length > 0) {
239704
+ if (walkDepth === 0 && exaHits.length > 0) {
239413
239705
  const richHit = pickAnswerHit(exaHits, raceProbeDomain);
239414
239706
  const candidates = exaHits.map((hit) => ({
239415
239707
  url: hit.url,
@@ -239442,6 +239734,40 @@ async function resolveAndExecute2(intent, params = {}, context, projection, opti
239442
239734
  skill_id: "exa-web-search",
239443
239735
  domain: exaSkillDomain
239444
239736
  };
239737
+ const topWalk = pickWalkTarget2(raceContextUrl, exaHits);
239738
+ if (topWalk?.url && walkDepth < 1) {
239739
+ try {
239740
+ const walked = await resolveAndExecute2(intent, params, { url: topWalk.url, domain: registrableHost2(topWalk.url) ?? undefined }, projection, { ...options ?? {}, __walkDepth: walkDepth + 1 });
239741
+ if (walked && walked.source !== "exa" && !walked.result?.exec_unsupported) {
239742
+ console.log(`[exa→walk] resolved candidate ${topWalk.url} via ${walked.source} (pointer pipe d${walkDepth + 1})`);
239743
+ {
239744
+ const wDom = context?.domain ?? (() => {
239745
+ try {
239746
+ return new URL(raceContextUrl).hostname;
239747
+ } catch {
239748
+ return null;
239749
+ }
239750
+ })();
239751
+ persistWalkedRoute2(clientScope, scopedCacheKey2(clientScope, buildResolveCacheKey2(wDom ?? null, intent, raceContextUrl)), walked);
239752
+ }
239753
+ return {
239754
+ ...walked,
239755
+ result: {
239756
+ ...walked.result,
239757
+ walked_from: "exa-web-search",
239758
+ exa_candidates: candidates,
239759
+ run_plan: [
239760
+ { step: "resolve", mode: "web-search", status: "hit", label: "fallback", error: null, source: webProvider ?? "exa" },
239761
+ { step: "walk", mode: walked.source, status: "hit", label: "top-candidate", error: null, source: walked.source }
239762
+ ]
239763
+ }
239764
+ };
239765
+ }
239766
+ console.log(`[exa→walk] candidate ${topWalk.url} produced no ladder rung — candidate leaf`);
239767
+ } catch (e) {
239768
+ console.log(`[exa→walk] walk error (${e.message}) — candidate leaf`);
239769
+ }
239770
+ }
239445
239771
  return {
239446
239772
  result: {
239447
239773
  ...richHit ? {
@@ -240218,7 +240544,7 @@ async function resolveAndExecute2(intent, params = {}, context, projection, opti
240218
240544
  console.log(`[ddg] $0 fallback failed: ${err.message}`);
240219
240545
  }
240220
240546
  }
240221
- if (viable.length === 0 && exaResults?.length) {
240547
+ if (walkDepth === 0 && viable.length === 0 && exaResults?.length) {
240222
240548
  const richHit = pickAnswerHit(exaResults, requestedDomain);
240223
240549
  if (richHit) {
240224
240550
  console.log(`[exa] returning highlights answer from ${richHit.url} (${(richHit.highlights ?? []).join(" ").length} chars) + ${exaResults.length} ranked candidate(s)`);
@@ -240241,6 +240567,31 @@ async function resolveAndExecute2(intent, params = {}, context, projection, opti
240241
240567
  fetch: `unbrowse fetch --url ${JSON.stringify(hit.url)}`
240242
240568
  }
240243
240569
  }));
240570
+ const topWalk = pickWalkTarget2(context?.url, exaResults);
240571
+ if (topWalk?.url && walkDepth < 1) {
240572
+ try {
240573
+ const walked = await resolveAndExecute2(intent, params, { url: topWalk.url, domain: registrableHost2(topWalk.url) ?? undefined }, projection, { ...options ?? {}, __walkDepth: walkDepth + 1 });
240574
+ if (walked && walked.source !== "exa" && !walked.result?.exec_unsupported) {
240575
+ console.log(`[exa→walk] resolved candidate ${topWalk.url} via ${walked.source} (pointer pipe d${walkDepth + 1})`);
240576
+ persistWalkedRoute2(clientScope, cacheKey2, walked);
240577
+ return {
240578
+ ...walked,
240579
+ result: {
240580
+ ...walked.result,
240581
+ walked_from: "exa-web-search",
240582
+ exa_candidates: candidates2,
240583
+ run_plan: [
240584
+ { step: "resolve", mode: "web-search", status: "hit", label: "fallback", error: null, source: serialWebProvider ?? "exa" },
240585
+ { step: "walk", mode: walked.source, status: "hit", label: "top-candidate", error: null, source: walked.source }
240586
+ ]
240587
+ }
240588
+ };
240589
+ }
240590
+ console.log(`[exa→walk] candidate ${topWalk.url} produced no ladder rung — exa leaf`);
240591
+ } catch (e) {
240592
+ console.log(`[exa→walk] walk error (${e.message}) — exa leaf`);
240593
+ }
240594
+ }
240244
240595
  return {
240245
240596
  result: {
240246
240597
  data: richHit.highlights,
@@ -241399,6 +241750,8 @@ var init_orchestrator2 = __esm(async () => {
241399
241750
  init_search_forms();
241400
241751
  init_ddg_search();
241401
241752
  init_cached_resolution();
241753
+ init_cardinality();
241754
+ init_cardinality();
241402
241755
  init_principal_scope();
241403
241756
  init_yield_safety();
241404
241757
  init_trace_store();
Binary file
@@ -2,7 +2,7 @@
2
2
  "repo_url": "https://github.com/justrach/kuri.git",
3
3
  "branch": "adding-extensions",
4
4
  "source_sha": "149881254046a20778f642b69f20f0c6468f6fb4",
5
- "built_at": "2026-06-17T20:24:54.012Z",
5
+ "built_at": "2026-06-18T02:47:19.984Z",
6
6
  "binaries": {
7
7
  "darwin-arm64": {
8
8
  "zig_target": "aarch64-macos",
@@ -21,11 +21,11 @@
21
21
  },
22
22
  "linux-x64": {
23
23
  "zig_target": "x86_64-linux",
24
- "sha256": "63a56d1b15d5ea1f7fe5f37157a1a018cbd1a9308c8dd126a4992a8d05a9970c"
24
+ "sha256": "ae7633e7140f4d98633aa28f3bcff33e1398f3caf709a530c6cd2b36c251d113"
25
25
  },
26
26
  "win-x64": {
27
27
  "zig_target": "x86_64-windows-gnu",
28
- "sha256": "24cf7b34a6d29b1bf9bd2dec1f616828cf88211a4c171b63b25265d467b93cb6",
28
+ "sha256": "54a2d73ab37bd056e5e469c9c8aeb5c992645962aee10465f1452a33fab447db",
29
29
  "source": "pre-staged"
30
30
  }
31
31
  },
@@ -33,22 +33,22 @@
33
33
  "darwin-arm64": {
34
34
  "zig_target": "aarch64-macos",
35
35
  "lib": "libkuri_ffi.dylib",
36
- "sha256": "3b2c830e62bfe76605bc1a0531f8af362cfaece72b3675511407c295f6768d1f"
36
+ "sha256": "774ff424fb6a4abb2634b7a891b10fa9760474851e2e7d25ebd6701917d959db"
37
37
  },
38
38
  "darwin-x64": {
39
39
  "zig_target": "x86_64-macos",
40
40
  "lib": "libkuri_ffi.dylib",
41
- "sha256": "b510792c338e0cc618e79cdacfe1b85258be9904d6768b089cc63ed561a631ba"
41
+ "sha256": "116afae77447b5036978d883541d264edbe3a2413788e904cf77b9123c0b79c3"
42
42
  },
43
43
  "linux-arm64": {
44
44
  "zig_target": "aarch64-linux",
45
45
  "lib": "libkuri_ffi.so",
46
- "sha256": "72335f81d0a6048b7228fece8fcce861884a059fb0ac4475a5577b5fa9b02ccf"
46
+ "sha256": "4558df5a2057910dd646491a9de9d1e8b81e958e0d830f1b33a1d30d0d91e95f"
47
47
  },
48
48
  "linux-x64": {
49
49
  "zig_target": "x86_64-linux",
50
50
  "lib": "libkuri_ffi.so",
51
- "sha256": "50db645f48c0d49d53733bc1eb099bc08a9a493c1f79f893566775700c504ecf"
51
+ "sha256": "b9bbb67c58aadfacbdf5304cdc7c1cea9014c6c3bb83dda7eb8661277f6c8b36"
52
52
  }
53
53
  }
54
54
  }
Binary file