unbrowse 2.12.2 → 2.12.7
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 +8 -44
- package/dist/cli.js +514 -20723
- package/package.json +4 -10
- package/runtime-src/api/routes.ts +15 -801
- package/runtime-src/auth/index.ts +32 -142
- package/runtime-src/capture/index.ts +101 -436
- package/runtime-src/cli.ts +371 -956
- package/runtime-src/client/index.ts +29 -622
- package/runtime-src/execution/index.ts +85 -345
- package/runtime-src/graph/index.ts +10 -128
- package/runtime-src/intent-match.ts +27 -27
- package/runtime-src/kuri/client.ts +82 -543
- package/runtime-src/orchestrator/index.ts +462 -2246
- package/runtime-src/reverse-engineer/index.ts +22 -220
- package/runtime-src/runtime/local-server.ts +16 -149
- package/runtime-src/runtime/paths.ts +5 -9
- package/runtime-src/runtime/setup.ts +1 -52
- package/runtime-src/server.ts +11 -6
- package/runtime-src/transform/schema-hints.ts +358 -0
- package/runtime-src/types/skill.ts +2 -49
- package/runtime-src/verification/index.ts +0 -15
- package/runtime-src/version.ts +13 -13
- package/vendor/kuri/darwin-arm64/kuri +0 -0
- package/vendor/kuri/darwin-x64/kuri +0 -0
- package/vendor/kuri/linux-arm64/kuri +0 -0
- package/vendor/kuri/linux-x64/kuri +0 -0
- package/bin/unbrowse-wrapper.mjs +0 -39
- package/bin/unbrowse.js +0 -38
- package/runtime-src/analytics-session.ts +0 -33
- package/runtime-src/api/browse-index.ts +0 -254
- package/runtime-src/api/browse-session.ts +0 -179
- package/runtime-src/api/browse-submit.ts +0 -455
- package/runtime-src/auth/runtime.ts +0 -116
- package/runtime-src/browser/index.ts +0 -635
- package/runtime-src/browser/types.ts +0 -41
- package/runtime-src/capture/prefetch.ts +0 -122
- package/runtime-src/capture/rsc.ts +0 -45
- package/runtime-src/cli/shortcuts.ts +0 -273
- package/runtime-src/client/graph-client.ts +0 -99
- package/runtime-src/execution/robots.ts +0 -167
- package/runtime-src/execution/search-forms.ts +0 -188
- package/runtime-src/graph/planner.ts +0 -411
- package/runtime-src/graph/session.ts +0 -294
- package/runtime-src/graph/trace-store.ts +0 -136
- package/runtime-src/indexer/index.ts +0 -480
- package/runtime-src/orchestrator/browser-agent.ts +0 -374
- package/runtime-src/orchestrator/dag-advisor.ts +0 -59
- package/runtime-src/orchestrator/dag-feedback.ts +0 -256
- package/runtime-src/orchestrator/first-pass-action.ts +0 -362
- package/runtime-src/orchestrator/passive-publish.ts +0 -152
- package/runtime-src/orchestrator/timing-economics.ts +0 -80
- package/runtime-src/payments/cascade.ts +0 -137
- package/runtime-src/payments/index.ts +0 -268
- package/runtime-src/payments/wallet.ts +0 -33
- package/runtime-src/reverse-engineer/description-prompt.ts +0 -132
- package/runtime-src/router.ts +0 -17
- package/runtime-src/runtime/browser-access.ts +0 -11
- package/runtime-src/runtime/browser-host.ts +0 -48
- package/runtime-src/runtime/lifecycle.ts +0 -17
- package/runtime-src/runtime/supervisor.ts +0 -69
- package/runtime-src/single-binary.ts +0 -141
- package/runtime-src/telemetry.ts +0 -253
- package/runtime-src/verification/matrix.ts +0 -30
- package/scripts/postinstall.mjs +0 -81
|
@@ -291,7 +291,7 @@ function inferRequires(endpoint: EndpointDescriptor): OperationBinding[] {
|
|
|
291
291
|
semantic_type: key.endsWith("_id") || key === "id" ? "identifier" : "input",
|
|
292
292
|
});
|
|
293
293
|
};
|
|
294
|
-
for (const key of Object.keys(endpoint.path_params ?? {})) add(key, "path_params"
|
|
294
|
+
for (const key of Object.keys(endpoint.path_params ?? {})) add(key, "path_params");
|
|
295
295
|
for (const key of Object.keys(endpoint.query ?? {})) add(normalizeQueryBindingKey(key), "query", false);
|
|
296
296
|
for (const match of endpoint.url_template.matchAll(/\{([^}]+)\}/g)) add(match[1], "url_template");
|
|
297
297
|
return requires;
|
|
@@ -411,20 +411,6 @@ function isGenericBindingKey(key: string | undefined): boolean {
|
|
|
411
411
|
return /^(id|ids|url|urls|page|cursor|offset|limit|slug(?:_\d+)?|pathname|domain|query|q|type|name)$/.test(key);
|
|
412
412
|
}
|
|
413
413
|
|
|
414
|
-
const PAGINATION_KEYS = new Set(["cursor", "page", "offset", "page_token", "next_cursor", "after", "before", "start", "next_page", "continuation_token", "skip", "from", "scroll_id"]);
|
|
415
|
-
function isPaginationBindingKey(key: string): boolean {
|
|
416
|
-
return PAGINATION_KEYS.has(key) || /^(next_|prev_|previous_)/.test(key) || /_cursor$/.test(key);
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
function classifyEdgeKind(source: SkillOperationNode, target: SkillOperationNode, bindingKey: string): SkillOperationEdge["kind"] {
|
|
420
|
-
if (source.operation_id === target.operation_id && isPaginationBindingKey(bindingKey)) return "pagination";
|
|
421
|
-
const LIST_ACTIONS = new Set(["list", "search", "timeline", "trending", "feed"]);
|
|
422
|
-
const DETAIL_ACTIONS = new Set(["detail", "fetch"]);
|
|
423
|
-
if (LIST_ACTIONS.has(source.action_kind) && DETAIL_ACTIONS.has(target.action_kind) && source.resource_kind === target.resource_kind && source.resource_kind !== "resource") return "parent_child";
|
|
424
|
-
if (target.auth_required && /^(auth|login|token|session|oauth)$/.test(source.action_kind)) return "auth";
|
|
425
|
-
return "dependency";
|
|
426
|
-
}
|
|
427
|
-
|
|
428
414
|
function isGenericSemanticType(type: string | undefined): boolean {
|
|
429
415
|
if (!type) return true;
|
|
430
416
|
return /^(identifier|input|resource|value|string|number|flag)$/.test(type);
|
|
@@ -576,27 +562,6 @@ export function resolveEndpointSemantic(
|
|
|
576
562
|
|
|
577
563
|
function buildOperationNode(endpoint: EndpointDescriptor): SkillOperationNode {
|
|
578
564
|
const semantic = resolveEndpointSemantic(endpoint);
|
|
579
|
-
const normalizedRequires = (() => {
|
|
580
|
-
const byBinding = new Map<string, OperationBinding>();
|
|
581
|
-
for (const binding of semantic.requires ?? []) {
|
|
582
|
-
const pathParamValue = (endpoint.path_params as Record<string, string> | undefined)?.[binding.key];
|
|
583
|
-
const defaultedPathParam =
|
|
584
|
-
binding.source === "path_params" &&
|
|
585
|
-
typeof pathParamValue === "string" && pathParamValue !== "";
|
|
586
|
-
const normalized = defaultedPathParam ? { ...binding, required: false } : binding;
|
|
587
|
-
const id = [normalized.key, normalized.source ?? "", normalized.semantic_type ?? ""].join("|");
|
|
588
|
-
const existing = byBinding.get(id);
|
|
589
|
-
if (!existing) {
|
|
590
|
-
byBinding.set(id, normalized);
|
|
591
|
-
continue;
|
|
592
|
-
}
|
|
593
|
-
byBinding.set(id, {
|
|
594
|
-
...existing,
|
|
595
|
-
required: existing.required && normalized.required,
|
|
596
|
-
});
|
|
597
|
-
}
|
|
598
|
-
return [...byBinding.values()];
|
|
599
|
-
})();
|
|
600
565
|
return {
|
|
601
566
|
operation_id: endpoint.endpoint_id,
|
|
602
567
|
endpoint_id: endpoint.endpoint_id,
|
|
@@ -608,7 +573,7 @@ function buildOperationNode(endpoint: EndpointDescriptor): SkillOperationNode {
|
|
|
608
573
|
description_in: semantic.description_in,
|
|
609
574
|
description_out: semantic.description_out,
|
|
610
575
|
response_summary: semantic.response_summary,
|
|
611
|
-
requires:
|
|
576
|
+
requires: semantic.requires ?? [],
|
|
612
577
|
provides: semantic.provides ?? [],
|
|
613
578
|
negative_tags: semantic.negative_tags ?? [],
|
|
614
579
|
example_request: semantic.example_request,
|
|
@@ -694,7 +659,7 @@ export function buildSkillOperationGraph(endpoints: EndpointDescriptor[]): Skill
|
|
|
694
659
|
for (const target of operations) {
|
|
695
660
|
for (const required of target.requires) {
|
|
696
661
|
for (const source of operations) {
|
|
697
|
-
if (source.operation_id === target.operation_id
|
|
662
|
+
if (source.operation_id === target.operation_id) continue;
|
|
698
663
|
const match = source.provides.find((provided) => {
|
|
699
664
|
const exactKeyMatch = provided.key === required.key && !isGenericBindingKey(required.key);
|
|
700
665
|
const semanticMatch =
|
|
@@ -702,14 +667,10 @@ export function buildSkillOperationGraph(endpoints: EndpointDescriptor[]): Skill
|
|
|
702
667
|
!!required.semantic_type &&
|
|
703
668
|
provided.semantic_type === required.semantic_type &&
|
|
704
669
|
!isGenericSemanticType(required.semantic_type);
|
|
705
|
-
|
|
706
|
-
source.operation_id === target.operation_id &&
|
|
707
|
-
provided.key === required.key &&
|
|
708
|
-
isPaginationBindingKey(required.key);
|
|
709
|
-
return exactKeyMatch || semanticMatch || paginationSelfMatch;
|
|
670
|
+
return exactKeyMatch || semanticMatch;
|
|
710
671
|
});
|
|
711
672
|
if (!match) continue;
|
|
712
|
-
if (
|
|
673
|
+
if (!isBefore(source.observed_at, target.observed_at)) continue;
|
|
713
674
|
const edgeId = `${source.operation_id}:${target.operation_id}:${required.key}`;
|
|
714
675
|
if (seenEdges.has(edgeId)) continue;
|
|
715
676
|
seenEdges.add(edgeId);
|
|
@@ -718,26 +679,14 @@ export function buildSkillOperationGraph(endpoints: EndpointDescriptor[]): Skill
|
|
|
718
679
|
from_operation_id: source.operation_id,
|
|
719
680
|
to_operation_id: target.operation_id,
|
|
720
681
|
binding_key: required.key,
|
|
721
|
-
kind: match.key === required.key ?
|
|
682
|
+
kind: match.key === required.key ? "dependency" : "hint",
|
|
722
683
|
confidence: match.key === required.key ? 0.9 : 0.6,
|
|
723
684
|
});
|
|
724
685
|
}
|
|
725
686
|
}
|
|
726
687
|
}
|
|
727
|
-
|
|
728
|
-
// Operations that are targets of dependency edges are not entry points
|
|
729
|
-
const dependencyTargets = new Set(
|
|
730
|
-
edges.filter((e) => e.kind === "dependency").map((e) => e.to_operation_id),
|
|
731
|
-
);
|
|
732
688
|
const entryOperationIds = operations
|
|
733
|
-
.filter(
|
|
734
|
-
(operation) =>
|
|
735
|
-
!dependencyTargets.has(operation.operation_id) &&
|
|
736
|
-
(operation.requires.length === 0 ||
|
|
737
|
-
operation.requires.every(
|
|
738
|
-
(binding) => binding.source === "query" || binding.source === "path_params",
|
|
739
|
-
)),
|
|
740
|
-
)
|
|
689
|
+
.filter((operation) => operation.requires.length === 0 || operation.requires.every((binding) => binding.source === "query"))
|
|
741
690
|
.map((operation) => operation.operation_id);
|
|
742
691
|
|
|
743
692
|
return {
|
|
@@ -749,12 +698,8 @@ export function buildSkillOperationGraph(endpoints: EndpointDescriptor[]): Skill
|
|
|
749
698
|
}
|
|
750
699
|
|
|
751
700
|
export function ensureSkillOperationGraph(skill: SkillManifest): SkillOperationGraph {
|
|
752
|
-
if (skill.
|
|
753
|
-
|
|
754
|
-
const graphOpIds = new Set(skill.operation_graph.operations.map((op) => op.operation_id));
|
|
755
|
-
const allCovered = skill.endpoints.every((ep) => graphOpIds.has(ep.endpoint_id));
|
|
756
|
-
if (allCovered) return skill.operation_graph;
|
|
757
|
-
}
|
|
701
|
+
if (skill.endpoints.length > 0) return buildSkillOperationGraph(skill.endpoints);
|
|
702
|
+
if (skill.operation_graph?.operations?.length) return skill.operation_graph;
|
|
758
703
|
return buildSkillOperationGraph(skill.endpoints);
|
|
759
704
|
}
|
|
760
705
|
|
|
@@ -782,7 +727,7 @@ export function knownBindingsFromInputs(
|
|
|
782
727
|
return known;
|
|
783
728
|
}
|
|
784
729
|
|
|
785
|
-
|
|
730
|
+
function isRunnable(operation: SkillOperationNode, bindings: Record<string, unknown>): boolean {
|
|
786
731
|
return operation.requires.every((binding) => {
|
|
787
732
|
if (!binding.required) return true;
|
|
788
733
|
const value = bindings[binding.key];
|
|
@@ -790,69 +735,6 @@ export function isRunnable(operation: SkillOperationNode, bindings: Record<strin
|
|
|
790
735
|
});
|
|
791
736
|
}
|
|
792
737
|
|
|
793
|
-
/**
|
|
794
|
-
* Compute the set of reachable operation IDs given current known bindings.
|
|
795
|
-
*
|
|
796
|
-
* An operation is reachable (A_reachable) if:
|
|
797
|
-
* 1. It has no required bindings (entry point), OR
|
|
798
|
-
* 2. All its required bindings are present in knownBindings, OR
|
|
799
|
-
* 3. All its required bindings can be transitively satisfied — either
|
|
800
|
-
* directly from knownBindings or from the provides of another
|
|
801
|
-
* reachable operation.
|
|
802
|
-
*
|
|
803
|
-
* Uses a fixpoint computation: starts with directly-runnable operations,
|
|
804
|
-
* then iteratively adds operations whose requirements are met by the
|
|
805
|
-
* accumulated provides of the reachable set, until no new operations
|
|
806
|
-
* are added.
|
|
807
|
-
*/
|
|
808
|
-
export function computeReachableEndpoints(
|
|
809
|
-
graph: SkillOperationGraph,
|
|
810
|
-
knownBindings: Record<string, unknown>,
|
|
811
|
-
): Set<string> {
|
|
812
|
-
const reachable = new Set<string>();
|
|
813
|
-
if (!graph.operations || graph.operations.length === 0) return reachable;
|
|
814
|
-
|
|
815
|
-
// Seed: operations that are directly runnable with current bindings
|
|
816
|
-
for (const op of graph.operations) {
|
|
817
|
-
if (isRunnable(op, knownBindings)) {
|
|
818
|
-
reachable.add(op.operation_id);
|
|
819
|
-
}
|
|
820
|
-
}
|
|
821
|
-
|
|
822
|
-
// Fixpoint expansion: iterate until stable
|
|
823
|
-
let changed = true;
|
|
824
|
-
while (changed) {
|
|
825
|
-
changed = false;
|
|
826
|
-
// Collect all binding keys provided by currently reachable operations
|
|
827
|
-
const availableKeys = new Set<string>(Object.keys(knownBindings));
|
|
828
|
-
for (const op of graph.operations) {
|
|
829
|
-
if (!reachable.has(op.operation_id)) continue;
|
|
830
|
-
for (const provided of op.provides) {
|
|
831
|
-
availableKeys.add(provided.key);
|
|
832
|
-
}
|
|
833
|
-
}
|
|
834
|
-
|
|
835
|
-
// Check each non-reachable operation
|
|
836
|
-
for (const op of graph.operations) {
|
|
837
|
-
if (reachable.has(op.operation_id)) continue;
|
|
838
|
-
const allSatisfied = op.requires.every((binding) => {
|
|
839
|
-
if (!binding.required) return true;
|
|
840
|
-
// Check direct bindings first
|
|
841
|
-
const directValue = knownBindings[binding.key];
|
|
842
|
-
if (directValue != null && directValue !== "") return true;
|
|
843
|
-
// Check if any reachable operation provides this key
|
|
844
|
-
return availableKeys.has(binding.key);
|
|
845
|
-
});
|
|
846
|
-
if (allSatisfied) {
|
|
847
|
-
reachable.add(op.operation_id);
|
|
848
|
-
changed = true;
|
|
849
|
-
}
|
|
850
|
-
}
|
|
851
|
-
}
|
|
852
|
-
|
|
853
|
-
return reachable;
|
|
854
|
-
}
|
|
855
|
-
|
|
856
738
|
export function getSkillChunk(
|
|
857
739
|
skill: SkillManifest,
|
|
858
740
|
opts?: {
|
|
@@ -1266,7 +1266,7 @@ function classifyRows(rows: unknown[], intent: string): { verdict: "pass" | "fai
|
|
|
1266
1266
|
hasAnyPath(row, ["full_name", "name", "repository.name", "path_with_namespace"]) &&
|
|
1267
1267
|
hasAnyPath(row, ["url", "web_url", "description", "stargazers_count", "stars", "star_count", "forks_count", "owner.login", "owner"])
|
|
1268
1268
|
);
|
|
1269
|
-
return matching.length >= 1 ? { verdict: "pass", reason: "repository_rows" } : { verdict: "
|
|
1269
|
+
return matching.length >= 1 ? { verdict: "pass", reason: "repository_rows" } : { verdict: "fail", reason: "wrong_entity_type" };
|
|
1270
1270
|
}
|
|
1271
1271
|
|
|
1272
1272
|
if (/\b(package|packages)\b/.test(lower)) {
|
|
@@ -1274,7 +1274,7 @@ function classifyRows(rows: unknown[], intent: string): { verdict: "pass" | "fai
|
|
|
1274
1274
|
hasAnyPath(row, ["name", "package.name"]) &&
|
|
1275
1275
|
hasAnyPath(row, ["version", "description", "summary", "url", "keywords", "requires_dist", "dependencies"])
|
|
1276
1276
|
);
|
|
1277
|
-
return matching.length >= 1 ? { verdict: "pass", reason: "package_rows" } : { verdict: "
|
|
1277
|
+
return matching.length >= 1 ? { verdict: "pass", reason: "package_rows" } : { verdict: "fail", reason: "wrong_entity_type" };
|
|
1278
1278
|
}
|
|
1279
1279
|
|
|
1280
1280
|
if (/\b(model|models)\b/.test(lower)) {
|
|
@@ -1282,7 +1282,7 @@ function classifyRows(rows: unknown[], intent: string): { verdict: "pass" | "fai
|
|
|
1282
1282
|
hasAnyPath(row, ["id", "modelId", "name"]) &&
|
|
1283
1283
|
hasAnyPath(row, ["downloads", "likes", "pipeline_tag", "url"])
|
|
1284
1284
|
);
|
|
1285
|
-
return matching.length >= 1 ? { verdict: "pass", reason: "model_rows" } : { verdict: "
|
|
1285
|
+
return matching.length >= 1 ? { verdict: "pass", reason: "model_rows" } : { verdict: "fail", reason: "wrong_entity_type" };
|
|
1286
1286
|
}
|
|
1287
1287
|
|
|
1288
1288
|
if (/\b(news|story|stories|article|articles|hacker news)\b/.test(lower)) {
|
|
@@ -1290,7 +1290,7 @@ function classifyRows(rows: unknown[], intent: string): { verdict: "pass" | "fai
|
|
|
1290
1290
|
hasAnyPath(row, ["objectID", "id", "url", "link"]) &&
|
|
1291
1291
|
hasAnyPath(row, ["title", "story_title", "author", "points", "num_comments", "meta"])
|
|
1292
1292
|
);
|
|
1293
|
-
return matching.length >= 1 ? { verdict: "pass", reason: "story_rows" } : { verdict: "
|
|
1293
|
+
return matching.length >= 1 ? { verdict: "pass", reason: "story_rows" } : { verdict: "fail", reason: "wrong_entity_type" };
|
|
1294
1294
|
}
|
|
1295
1295
|
|
|
1296
1296
|
if (/\bsearch images\b/.test(lower)) {
|
|
@@ -1298,7 +1298,7 @@ function classifyRows(rows: unknown[], intent: string): { verdict: "pass" | "fai
|
|
|
1298
1298
|
hasAnyPath(row, ["repo_name", "name", "full_name"]) &&
|
|
1299
1299
|
hasAnyPath(row, ["short_description", "description", "star_count", "pull_count", "url"])
|
|
1300
1300
|
);
|
|
1301
|
-
return matching.length >= 1 ? { verdict: "pass", reason: "image_rows" } : { verdict: "
|
|
1301
|
+
return matching.length >= 1 ? { verdict: "pass", reason: "image_rows" } : { verdict: "fail", reason: "wrong_entity_type" };
|
|
1302
1302
|
}
|
|
1303
1303
|
|
|
1304
1304
|
if (/\b(get )?image tags\b/.test(lower)) {
|
|
@@ -1306,7 +1306,7 @@ function classifyRows(rows: unknown[], intent: string): { verdict: "pass" | "fai
|
|
|
1306
1306
|
hasAnyPath(row, ["name", "tag"]) &&
|
|
1307
1307
|
hasAnyPath(row, ["last_updated", "updated_at", "full_size", "digest"])
|
|
1308
1308
|
);
|
|
1309
|
-
return matching.length >= 1 ? { verdict: "pass", reason: "tag_rows" } : { verdict: "
|
|
1309
|
+
return matching.length >= 1 ? { verdict: "pass", reason: "tag_rows" } : { verdict: "fail", reason: "wrong_entity_type" };
|
|
1310
1310
|
}
|
|
1311
1311
|
|
|
1312
1312
|
if (/\b(company|companies|organization|organisations|business)\b/.test(lower)) {
|
|
@@ -1314,7 +1314,7 @@ function classifyRows(rows: unknown[], intent: string): { verdict: "pass" | "fai
|
|
|
1314
1314
|
hasAnyPath(row, ["name", "title", "public_identifier"]) &&
|
|
1315
1315
|
hasAnyPath(row, ["description", "industry", "url", "website", "employee_count", "follower_count"])
|
|
1316
1316
|
);
|
|
1317
|
-
return matching.length >= 1 ? { verdict: "pass", reason: "company_rows" } : { verdict: "
|
|
1317
|
+
return matching.length >= 1 ? { verdict: "pass", reason: "company_rows" } : { verdict: "fail", reason: "wrong_entity_type" };
|
|
1318
1318
|
}
|
|
1319
1319
|
|
|
1320
1320
|
if (/\b(person|people|profile|profiles|member|members|user|users)\b/.test(lower)) {
|
|
@@ -1323,7 +1323,7 @@ function classifyRows(rows: unknown[], intent: string): { verdict: "pass" | "fai
|
|
|
1323
1323
|
hasAnyPath(row, ["headline", "url", "public_identifier", "username"])
|
|
1324
1324
|
);
|
|
1325
1325
|
const minRows = /\b(profile|profiles|user|users|person)\b/.test(lower) && !/\bsearch\b/.test(lower) ? 1 : 2;
|
|
1326
|
-
return matching.length >= minRows ? { verdict: "pass", reason: "people_rows" } : { verdict: "
|
|
1326
|
+
return matching.length >= minRows ? { verdict: "pass", reason: "people_rows" } : { verdict: "fail", reason: "wrong_entity_type" };
|
|
1327
1327
|
}
|
|
1328
1328
|
|
|
1329
1329
|
if (/\b(comment|comments)\b/.test(lower)) {
|
|
@@ -1331,7 +1331,7 @@ function classifyRows(rows: unknown[], intent: string): { verdict: "pass" | "fai
|
|
|
1331
1331
|
hasAnyPath(row, ["id", "url", "permalink"]) &&
|
|
1332
1332
|
hasAnyPath(row, ["author", "body", "text"])
|
|
1333
1333
|
);
|
|
1334
|
-
return matching.length >= 1 ? { verdict: "pass", reason: "comment_rows" } : { verdict: "
|
|
1334
|
+
return matching.length >= 1 ? { verdict: "pass", reason: "comment_rows" } : { verdict: "fail", reason: "wrong_entity_type" };
|
|
1335
1335
|
}
|
|
1336
1336
|
|
|
1337
1337
|
if (/\b(email|emails|mail|inbox)\b/.test(lower)) {
|
|
@@ -1340,20 +1340,20 @@ function classifyRows(rows: unknown[], intent: string): { verdict: "pass" | "fai
|
|
|
1340
1340
|
hasAnyPath(row, ["subject", "thread.subject", "from", "sender", "thread.latest_sender_name"]) &&
|
|
1341
1341
|
hasAnyPath(row, ["date", "thread.formatted_date", "preview", "thread.preview", "matchedEmail.content_markdown"])
|
|
1342
1342
|
);
|
|
1343
|
-
return matching.length >= 1 ? { verdict: "pass", reason: "email_rows" } : { verdict: "
|
|
1343
|
+
return matching.length >= 1 ? { verdict: "pass", reason: "email_rows" } : { verdict: "fail", reason: "wrong_entity_type" };
|
|
1344
1344
|
}
|
|
1345
1345
|
|
|
1346
1346
|
if (/\b(post|posts|tweet|tweets|status|statuses)\b/.test(lower)) {
|
|
1347
1347
|
const matching = objects.filter((row) =>
|
|
1348
|
-
hasAnyPath(row, ["id", "url", "uri", "permalink"
|
|
1348
|
+
hasAnyPath(row, ["id", "url", "uri", "permalink"]) &&
|
|
1349
1349
|
countMatchingGroups(row, [
|
|
1350
|
-
["content", "text", "title", "body"
|
|
1351
|
-
["account.username", "account.acct", "username", "author", "user.name"
|
|
1352
|
-
["score", "points", "likes", "favorite_count", "num_comments", "reply_count"
|
|
1353
|
-
["date", "created_at", "published_at", "timestamp", "meta"
|
|
1350
|
+
["content", "text", "title", "body"],
|
|
1351
|
+
["account.username", "account.acct", "username", "author", "user.name"],
|
|
1352
|
+
["score", "points", "likes", "favorite_count", "num_comments", "reply_count"],
|
|
1353
|
+
["date", "created_at", "published_at", "timestamp", "meta"],
|
|
1354
1354
|
]) >= 2
|
|
1355
1355
|
);
|
|
1356
|
-
return matching.length >= 1 ? { verdict: "pass", reason: "post_rows" } : { verdict: "
|
|
1356
|
+
return matching.length >= 1 ? { verdict: "pass", reason: "post_rows" } : { verdict: "fail", reason: "wrong_entity_type" };
|
|
1357
1357
|
}
|
|
1358
1358
|
|
|
1359
1359
|
if (/\b(reddit|subreddit)\b/.test(lower)) {
|
|
@@ -1362,7 +1362,7 @@ function classifyRows(rows: unknown[], intent: string): { verdict: "pass" | "fai
|
|
|
1362
1362
|
hasAnyPath(row, ["title", "subreddit", "author"]) &&
|
|
1363
1363
|
hasAnyPath(row, ["num_comments", "score", "permalink"])
|
|
1364
1364
|
);
|
|
1365
|
-
return matching.length >= 1 ? { verdict: "pass", reason: "reddit_post_rows" } : { verdict: "
|
|
1365
|
+
return matching.length >= 1 ? { verdict: "pass", reason: "reddit_post_rows" } : { verdict: "fail", reason: "wrong_entity_type" };
|
|
1366
1366
|
}
|
|
1367
1367
|
|
|
1368
1368
|
if (/\b(topic|topics|trend|trending|hashtag|hashtags)\b/.test(lower)) {
|
|
@@ -1370,7 +1370,7 @@ function classifyRows(rows: unknown[], intent: string): { verdict: "pass" | "fai
|
|
|
1370
1370
|
hasAnyPath(row, ["name", "title", "query"]) &&
|
|
1371
1371
|
hasAnyPath(row, ["url", "name", "query"])
|
|
1372
1372
|
);
|
|
1373
|
-
return matching.length >= 2 ? { verdict: "pass", reason: "topic_rows" } : { verdict: "
|
|
1373
|
+
return matching.length >= 2 ? { verdict: "pass", reason: "topic_rows" } : { verdict: "fail", reason: "wrong_entity_type" };
|
|
1374
1374
|
}
|
|
1375
1375
|
|
|
1376
1376
|
if (/\b(doc|docs|documentation)\b/.test(lower)) {
|
|
@@ -1379,7 +1379,7 @@ function classifyRows(rows: unknown[], intent: string): { verdict: "pass" | "fai
|
|
|
1379
1379
|
hasAnyPath(row, ["url", "link", "href", "mdn_url"]) &&
|
|
1380
1380
|
hasAnyPath(row, ["summary", "description", "slug", "popularity", "score"])
|
|
1381
1381
|
);
|
|
1382
|
-
return matching.length >= 1 ? { verdict: "pass", reason: "document_rows" } : { verdict: "
|
|
1382
|
+
return matching.length >= 1 ? { verdict: "pass", reason: "document_rows" } : { verdict: "fail", reason: "wrong_entity_type" };
|
|
1383
1383
|
}
|
|
1384
1384
|
|
|
1385
1385
|
if (/\b(paper|papers)\b/.test(lower)) {
|
|
@@ -1388,7 +1388,7 @@ function classifyRows(rows: unknown[], intent: string): { verdict: "pass" | "fai
|
|
|
1388
1388
|
hasAnyPath(row, ["url", "link", "href"]) &&
|
|
1389
1389
|
hasAnyPath(row, ["summary", "description", "author", "authors", "date", "published", "meta"])
|
|
1390
1390
|
);
|
|
1391
|
-
return matching.length >= 1 ? { verdict: "pass", reason: "paper_rows" } : { verdict: "
|
|
1391
|
+
return matching.length >= 1 ? { verdict: "pass", reason: "paper_rows" } : { verdict: "fail", reason: "wrong_entity_type" };
|
|
1392
1392
|
}
|
|
1393
1393
|
|
|
1394
1394
|
if (/\b(question|questions)\b/.test(lower)) {
|
|
@@ -1401,7 +1401,7 @@ function classifyRows(rows: unknown[], intent: string): { verdict: "pass" | "fai
|
|
|
1401
1401
|
["author", "date", "created_at", "meta"],
|
|
1402
1402
|
]) >= 2
|
|
1403
1403
|
);
|
|
1404
|
-
return matching.length >= 2 ? { verdict: "pass", reason: "question_rows" } : { verdict: "
|
|
1404
|
+
return matching.length >= 2 ? { verdict: "pass", reason: "question_rows" } : { verdict: "fail", reason: "wrong_entity_type" };
|
|
1405
1405
|
}
|
|
1406
1406
|
|
|
1407
1407
|
if (/\b(recipe|recipes)\b/.test(lower)) {
|
|
@@ -1410,7 +1410,7 @@ function classifyRows(rows: unknown[], intent: string): { verdict: "pass" | "fai
|
|
|
1410
1410
|
hasAnyPath(row, ["url", "link", "href"]) &&
|
|
1411
1411
|
hasAnyPath(row, ["rating", "review_count", "author", "description", "summary", "cook_time", "total_time"])
|
|
1412
1412
|
);
|
|
1413
|
-
return matching.length >= 1 ? { verdict: "pass", reason: "recipe_rows" } : { verdict: "
|
|
1413
|
+
return matching.length >= 1 ? { verdict: "pass", reason: "recipe_rows" } : { verdict: "fail", reason: "wrong_entity_type" };
|
|
1414
1414
|
}
|
|
1415
1415
|
|
|
1416
1416
|
if (/\b(course|courses)\b/.test(lower)) {
|
|
@@ -1419,7 +1419,7 @@ function classifyRows(rows: unknown[], intent: string): { verdict: "pass" | "fai
|
|
|
1419
1419
|
hasAnyPath(row, ["url", "link", "href"]) &&
|
|
1420
1420
|
hasAnyPath(row, ["rating", "partner", "provider", "instructor", "description", "summary", "duration", "level"])
|
|
1421
1421
|
);
|
|
1422
|
-
return matching.length >= 1 ? { verdict: "pass", reason: "course_rows" } : { verdict: "
|
|
1422
|
+
return matching.length >= 1 ? { verdict: "pass", reason: "course_rows" } : { verdict: "fail", reason: "wrong_entity_type" };
|
|
1423
1423
|
}
|
|
1424
1424
|
|
|
1425
1425
|
if (/\b(definition|dictionary|meaning)\b/.test(lower)) {
|
|
@@ -1427,7 +1427,7 @@ function classifyRows(rows: unknown[], intent: string): { verdict: "pass" | "fai
|
|
|
1427
1427
|
hasAnyPath(row, ["term", "title", "name", "word"]) &&
|
|
1428
1428
|
hasAnyPath(row, ["definition", "summary", "body", "description"])
|
|
1429
1429
|
);
|
|
1430
|
-
return matching.length >= 1 ? { verdict: "pass", reason: "definition_rows" } : { verdict: "
|
|
1430
|
+
return matching.length >= 1 ? { verdict: "pass", reason: "definition_rows" } : { verdict: "fail", reason: "wrong_entity_type" };
|
|
1431
1431
|
}
|
|
1432
1432
|
|
|
1433
1433
|
if (/\b(stock|stocks|ticker|tickers|quote|quotes)\b/.test(lower)) {
|
|
@@ -1436,7 +1436,7 @@ function classifyRows(rows: unknown[], intent: string): { verdict: "pass" | "fai
|
|
|
1436
1436
|
hasAnyPath(row, ["price", "regularMarketPrice", "current_price"]) &&
|
|
1437
1437
|
hasAnyPath(row, ["name", "currency", "change_percent", "market_cap", "market_state"])
|
|
1438
1438
|
);
|
|
1439
|
-
return matching.length >= 1 ? { verdict: "pass", reason: "quote_rows" } : { verdict: "
|
|
1439
|
+
return matching.length >= 1 ? { verdict: "pass", reason: "quote_rows" } : { verdict: "fail", reason: "wrong_entity_type" };
|
|
1440
1440
|
}
|
|
1441
1441
|
|
|
1442
1442
|
if (/\b(product|products|item|items)\b/.test(lower)) {
|
|
@@ -1453,7 +1453,7 @@ function classifyRows(rows: unknown[], intent: string): { verdict: "pass" | "fai
|
|
|
1453
1453
|
String(getPath(row, "url") ?? ""),
|
|
1454
1454
|
)
|
|
1455
1455
|
);
|
|
1456
|
-
return matching.length >= 1 ? { verdict: "pass", reason: "product_rows" } : { verdict: "
|
|
1456
|
+
return matching.length >= 1 ? { verdict: "pass", reason: "product_rows" } : { verdict: "fail", reason: "wrong_entity_type" };
|
|
1457
1457
|
}
|
|
1458
1458
|
|
|
1459
1459
|
if (/\b(channel|channels|server|servers|guild|guilds|workspace|workspaces)\b/.test(lower)) {
|
|
@@ -1462,7 +1462,7 @@ function classifyRows(rows: unknown[], intent: string): { verdict: "pass" | "fai
|
|
|
1462
1462
|
hasAnyPath(row, ["id", "url", "channel_id", "guild_id", "workspace_id"]) &&
|
|
1463
1463
|
hasAnyPath(row, ["description", "type", "member_count", "url"])
|
|
1464
1464
|
);
|
|
1465
|
-
return matching.length >= 1 ? { verdict: "pass", reason: "channel_rows" } : { verdict: "
|
|
1465
|
+
return matching.length >= 1 ? { verdict: "pass", reason: "channel_rows" } : { verdict: "fail", reason: "wrong_entity_type" };
|
|
1466
1466
|
}
|
|
1467
1467
|
|
|
1468
1468
|
return { verdict: "skip", reason: "unclassified_array" };
|