@untangle-code/search 0.0.0-stage → 0.1.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.
Files changed (140) hide show
  1. package/LICENSE +661 -0
  2. package/NOTICE +90 -0
  3. package/README.md +433 -2
  4. package/THIRD_PARTY_LICENSES.md +29 -0
  5. package/dist/benchmark-integrity.d.ts +12 -0
  6. package/dist/benchmark-integrity.d.ts.map +1 -0
  7. package/dist/benchmark-integrity.js +10 -0
  8. package/dist/benchmark-integrity.js.map +1 -0
  9. package/dist/bm25.d.ts +46 -0
  10. package/dist/bm25.d.ts.map +1 -0
  11. package/dist/bm25.js +105 -0
  12. package/dist/bm25.js.map +1 -0
  13. package/dist/deadline.d.ts +4 -0
  14. package/dist/deadline.d.ts.map +1 -0
  15. package/dist/deadline.js +54 -0
  16. package/dist/deadline.js.map +1 -0
  17. package/dist/dedupe.d.ts +48 -0
  18. package/dist/dedupe.d.ts.map +1 -0
  19. package/dist/dedupe.js +58 -0
  20. package/dist/dedupe.js.map +1 -0
  21. package/dist/diversify.d.ts +45 -0
  22. package/dist/diversify.d.ts.map +1 -0
  23. package/dist/diversify.js +30 -0
  24. package/dist/diversify.js.map +1 -0
  25. package/dist/engine.d.ts +157 -0
  26. package/dist/engine.d.ts.map +1 -0
  27. package/dist/engine.js +1498 -0
  28. package/dist/engine.js.map +1 -0
  29. package/dist/enrichment.d.ts +16 -0
  30. package/dist/enrichment.d.ts.map +1 -0
  31. package/dist/enrichment.js +92 -0
  32. package/dist/enrichment.js.map +1 -0
  33. package/dist/filter.d.ts +86 -0
  34. package/dist/filter.d.ts.map +1 -0
  35. package/dist/filter.js +166 -0
  36. package/dist/filter.js.map +1 -0
  37. package/dist/findability.d.ts +144 -0
  38. package/dist/findability.d.ts.map +1 -0
  39. package/dist/findability.js +393 -0
  40. package/dist/findability.js.map +1 -0
  41. package/dist/format.d.ts +28 -0
  42. package/dist/format.d.ts.map +1 -0
  43. package/dist/format.js +172 -0
  44. package/dist/format.js.map +1 -0
  45. package/dist/fusion.d.ts +47 -0
  46. package/dist/fusion.d.ts.map +1 -0
  47. package/dist/fusion.js +84 -0
  48. package/dist/fusion.js.map +1 -0
  49. package/dist/glob.d.ts +50 -0
  50. package/dist/glob.d.ts.map +1 -0
  51. package/dist/glob.js +144 -0
  52. package/dist/glob.js.map +1 -0
  53. package/dist/grep.d.ts +76 -0
  54. package/dist/grep.d.ts.map +1 -0
  55. package/dist/grep.js +475 -0
  56. package/dist/grep.js.map +1 -0
  57. package/dist/index.d.ts +42 -0
  58. package/dist/index.d.ts.map +1 -0
  59. package/dist/index.js +63 -0
  60. package/dist/index.js.map +1 -0
  61. package/dist/ledger.d.ts +45 -0
  62. package/dist/ledger.d.ts.map +1 -0
  63. package/dist/ledger.js +39 -0
  64. package/dist/ledger.js.map +1 -0
  65. package/dist/payload.d.ts +108 -0
  66. package/dist/payload.d.ts.map +1 -0
  67. package/dist/payload.js +263 -0
  68. package/dist/payload.js.map +1 -0
  69. package/dist/port.d.ts +112 -0
  70. package/dist/port.d.ts.map +1 -0
  71. package/dist/port.js +2 -0
  72. package/dist/port.js.map +1 -0
  73. package/dist/product-complexity.d.ts +89 -0
  74. package/dist/product-complexity.d.ts.map +1 -0
  75. package/dist/product-complexity.js +1367 -0
  76. package/dist/product-complexity.js.map +1 -0
  77. package/dist/regex-safety.d.ts +75 -0
  78. package/dist/regex-safety.d.ts.map +1 -0
  79. package/dist/regex-safety.js +902 -0
  80. package/dist/regex-safety.js.map +1 -0
  81. package/dist/relevance-prerequisites.d.ts +21 -0
  82. package/dist/relevance-prerequisites.d.ts.map +1 -0
  83. package/dist/relevance-prerequisites.js +47 -0
  84. package/dist/relevance-prerequisites.js.map +1 -0
  85. package/dist/relevance.d.ts +107 -0
  86. package/dist/relevance.d.ts.map +1 -0
  87. package/dist/relevance.js +199 -0
  88. package/dist/relevance.js.map +1 -0
  89. package/dist/retrieval.d.ts +46 -0
  90. package/dist/retrieval.d.ts.map +1 -0
  91. package/dist/retrieval.js +182 -0
  92. package/dist/retrieval.js.map +1 -0
  93. package/dist/scoring.d.ts +102 -0
  94. package/dist/scoring.d.ts.map +1 -0
  95. package/dist/scoring.js +175 -0
  96. package/dist/scoring.js.map +1 -0
  97. package/dist/sort.d.ts +21 -0
  98. package/dist/sort.d.ts.map +1 -0
  99. package/dist/sort.js +53 -0
  100. package/dist/sort.js.map +1 -0
  101. package/dist/symbol-match.d.ts +21 -0
  102. package/dist/symbol-match.d.ts.map +1 -0
  103. package/dist/symbol-match.js +72 -0
  104. package/dist/symbol-match.js.map +1 -0
  105. package/dist/tokenize.d.ts +41 -0
  106. package/dist/tokenize.d.ts.map +1 -0
  107. package/dist/tokenize.js +202 -0
  108. package/dist/tokenize.js.map +1 -0
  109. package/dist/types.d.ts +173 -0
  110. package/dist/types.d.ts.map +1 -0
  111. package/dist/types.js +42 -0
  112. package/dist/types.js.map +1 -0
  113. package/package.json +61 -3
  114. package/src/benchmark-integrity.ts +25 -0
  115. package/src/bm25.ts +135 -0
  116. package/src/deadline.ts +59 -0
  117. package/src/dedupe.ts +99 -0
  118. package/src/diversify.ts +71 -0
  119. package/src/engine.ts +1957 -0
  120. package/src/enrichment.ts +115 -0
  121. package/src/filter.ts +267 -0
  122. package/src/findability.ts +580 -0
  123. package/src/format.ts +228 -0
  124. package/src/fusion.ts +121 -0
  125. package/src/glob.ts +151 -0
  126. package/src/grep.ts +618 -0
  127. package/src/index.ts +83 -0
  128. package/src/ledger.ts +72 -0
  129. package/src/payload.ts +382 -0
  130. package/src/port.ts +133 -0
  131. package/src/product-complexity.ts +2168 -0
  132. package/src/regex-safety.ts +1002 -0
  133. package/src/relevance-prerequisites.ts +83 -0
  134. package/src/relevance.ts +328 -0
  135. package/src/retrieval.ts +299 -0
  136. package/src/scoring.ts +321 -0
  137. package/src/sort.ts +86 -0
  138. package/src/symbol-match.ts +87 -0
  139. package/src/tokenize.ts +213 -0
  140. package/src/types.ts +206 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ledger.d.ts","sourceRoot":"","sources":["../src/ledger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAG3E,uEAAuE;AACvE,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,iBAAiB,CAAC,aAAa,CAAC,CAAC;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,UAAU,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;;;;GAKG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2B;IAE5C,GAAG,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI;IAgBxC,6DAA6D;IACtD,YAAY,CAAC,KAAK,EAAE,IAAI,CAAC,eAAe,EAAE,aAAa,CAAC,GAAG;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAI9F,IAAW,IAAI,IAAI,MAAM,CAExB;IAED,8DAA8D;IACvD,OAAO,IAAI,iBAAiB,EAAE;IAIrC,2EAA2E;IACpE,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;CAG7D"}
package/dist/ledger.js ADDED
@@ -0,0 +1,39 @@
1
+ import { buildSkipLedgerEntry, summarizeSkipReasons } from "@untangle-code/domain";
2
+ /**
3
+ * Sammelt Ledger-Eintraege einer einzelnen Suchausfuehrung.
4
+ *
5
+ * `add()` verweigert (ueber `buildSkipLedgerEntry`) eine leere Begruendung —
6
+ * ein Uebersprungeintrag ohne Grund taeuscht Diagnose vor, wo keine ist.
7
+ */
8
+ export class SearchSkipLedger {
9
+ entries = [];
10
+ add(input) {
11
+ this.entries.push(buildSkipLedgerEntry({
12
+ stage: "search",
13
+ subjectKind: input.subjectKind,
14
+ ...(input.subjectId === undefined ? {} : { subjectId: input.subjectId }),
15
+ ...(input.path === undefined ? {} : { path: input.path }),
16
+ ...(input.repoId === undefined ? {} : { repoId: input.repoId }),
17
+ ...(input.refId === undefined ? {} : { refId: input.refId }),
18
+ reason: input.reason,
19
+ detail: input.detail,
20
+ recoverable: input.recoverable ?? false,
21
+ }));
22
+ }
23
+ /** Ein Kandidat, der die Trefferliste nicht erreicht hat. */
24
+ addCandidate(input) {
25
+ this.add({ subjectKind: "search_candidate", ...input });
26
+ }
27
+ get size() {
28
+ return this.entries.length;
29
+ }
30
+ /** Kopie der gesammelten Eintraege in Einfuegereihenfolge. */
31
+ toArray() {
32
+ return [...this.entries];
33
+ }
34
+ /** Zaehlung je Grund — dieselbe Form wie `SkipLedgerV1.countsByReason`. */
35
+ countsByReason() {
36
+ return summarizeSkipReasons(this.entries);
37
+ }
38
+ }
39
+ //# sourceMappingURL=ledger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ledger.js","sourceRoot":"","sources":["../src/ledger.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAcnF;;;;;GAKG;AACH,MAAM,OAAO,gBAAgB;IACV,OAAO,GAAwB,EAAE,CAAC;IAE5C,GAAG,CAAC,KAAsB;QAC/B,IAAI,CAAC,OAAO,CAAC,IAAI,CACf,oBAAoB,CAAC;YACnB,KAAK,EAAE,QAAQ;YACf,WAAW,EAAE,KAAK,CAAC,WAAW;YAC9B,GAAG,CAAC,KAAK,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC;YACxE,GAAG,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC;YACzD,GAAG,CAAC,KAAK,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC;YAC/D,GAAG,CAAC,KAAK,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC;YAC5D,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,WAAW,EAAE,KAAK,CAAC,WAAW,IAAI,KAAK;SACxC,CAAC,CACH,CAAC;IACJ,CAAC;IAED,6DAA6D;IACtD,YAAY,CAAC,KAAmE;QACrF,IAAI,CAAC,GAAG,CAAC,EAAE,WAAW,EAAE,kBAAkB,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC;IAC1D,CAAC;IAED,IAAW,IAAI;QACb,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;IAC7B,CAAC;IAED,8DAA8D;IACvD,OAAO;QACZ,OAAO,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC;IAC3B,CAAC;IAED,2EAA2E;IACpE,cAAc;QACnB,OAAO,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC5C,CAAC;CACF"}
@@ -0,0 +1,108 @@
1
+ /**
2
+ * Lesen und Pruefen des gespeicherten Chunk-Payloads (spec.md §10.3).
3
+ *
4
+ * Der `VectorStore`-Port liefert `payload?: Record<string, unknown>` — also
5
+ * ungetypte Daten aus dem Speicher. Sie hier EINMAL zu pruefen und danach mit
6
+ * `CodeChunkPayloadV1` weiterzuarbeiten ist der Unterschied zwischen einem
7
+ * Treffer, dem man ansieht warum er unvollstaendig ist, und einem `undefined`,
8
+ * das drei Stufen spaeter als leeres Feld auftaucht.
9
+ *
10
+ * E4: Ein Punkt mit unbrauchbarem Payload wird NICHT stillschweigend
11
+ * uebersprungen. `readCodeChunkPayload` liefert den Grund als Text zurueck,
12
+ * und der Aufrufer schreibt ihn in den Skip-Ledger.
13
+ */
14
+ import type { CodeChunkPayloadV1, ScoredPointV1 } from "@untangle-code/domain";
15
+ /**
16
+ * Ergebnis des Payload-Lesens: entweder ein Chunk oder ein benannter Grund.
17
+ *
18
+ * `substitutedFields` ist der zweite Teil der Ehrlichkeit (E4): ein Payload
19
+ * kann LESBAR sein und trotzdem Felder vermissen lassen, die dann durch
20
+ * dokumentierte Ersatzwerte gefuellt werden. Ohne diese Liste sieht der
21
+ * Treffer in jedem Feld vollstaendig aus — und genau das ist die stille
22
+ * Beschoenigung, die E4 verbietet. Die Liste ist nach Codepoints sortiert und
23
+ * leer, wenn nichts ersetzt wurde.
24
+ */
25
+ export type PayloadReadResult = {
26
+ ok: true;
27
+ payload: CodeChunkPayloadV1;
28
+ substitutedFields: string[];
29
+ } | {
30
+ ok: false;
31
+ reason: string;
32
+ };
33
+ /**
34
+ * Prueft einen rohen Payload auf die Felder, die der Abrufkern braucht, und
35
+ * fuellt fehlende OPTIONALE Felder mit dokumentierten Ersatzwerten:
36
+ * `repo_label` faellt auf `repo_id` zurueck, `ref_name` auf `ref_id`,
37
+ * `language` auf `"unknown"`, `parse_quality` auf `"failed"` (nicht auf
38
+ * `"complete"` — eine unbekannte Parsequalitaet als vollstaendig auszugeben
39
+ * waere genau die stille Beschoenigung, die BUILD_PLAN E4 verbietet).
40
+ *
41
+ * JEDER dieser Ersatzwerte wird in `substitutedFields` genannt. Der Aufrufer
42
+ * traegt die Liste weiter (`SearchHitV1.incompletePayloadFields`), damit ein
43
+ * Leser den geratenen Wert vom gespeicherten unterscheiden kann.
44
+ *
45
+ * Der BEREICH ist davon ausgenommen: ein fehlendes `end_line` faellt auf
46
+ * `start_line` zurueck, ein fehlendes `end_byte` auf `start_byte` — nie auf 0,
47
+ * denn ein `SourceRange` mit `endByte < startByte` ist nicht ungenau, sondern
48
+ * UNGUELTIG; wer damit eine Datei aufschneidet, bekommt die falsche Stelle.
49
+ * Ist ein Bereich im gespeicherten Payload selbst ungueltig, wird der Punkt
50
+ * abgelehnt statt zurechtgebogen.
51
+ */
52
+ export declare function readCodeChunkPayload(raw: Record<string, unknown> | undefined): PayloadReadResult;
53
+ /**
54
+ * Ein Kandidat des Abrufkerns: gepruefter Payload plus die Rohsignale, mit
55
+ * denen ihn der Speicher geliefert hat.
56
+ */
57
+ export interface SearchCandidate {
58
+ /** Punkt-ID im Vektorspeicher. */
59
+ pointId: string;
60
+ payload: CodeChunkPayloadV1;
61
+ /**
62
+ * Der rohe Payload, unveraendert. `CodeChunkPayloadV1` beschreibt die
63
+ * Pflichtfelder aus spec.md §10.3; Felder, die spec.md §10.4 zusaetzlich
64
+ * indiziert (etwa `changed_at_epoch_ms`) oder die eine spaetere Generation
65
+ * hinzufuegt (`generation_id`), gehen dadurch NICHT verloren.
66
+ */
67
+ raw: Record<string, unknown>;
68
+ /** Cosine-Score des dichten Zweigs, sofern der Kandidat dort auftauchte. */
69
+ denseScore?: number;
70
+ /** 1-basierter Rang im dichten Zweig. */
71
+ denseRank?: number;
72
+ /** Roher BM25-Wert des lexikalischen Zweigs (in diesem Paket berechnet). */
73
+ lexicalScore?: number;
74
+ /** 1-basierter Rang im lexikalischen Zweig. */
75
+ lexicalRank?: number;
76
+ /** 1-basierter Rang im Zweig der exakten Symbolnamen-Treffer. */
77
+ symbolRank?: number;
78
+ /** Staerke des Symbolnamen-Treffers in [0, 1] (siehe `symbol-match.ts`). */
79
+ symbolMatchStrength?: number;
80
+ /** Beleg des Symbolnamen-Treffers, z. B. `symbol_name == "charge"`. */
81
+ symbolMatchEvidence?: string;
82
+ /**
83
+ * Payload-Felder, die im Speicher fehlten und durch Ersatzwerte gefuellt
84
+ * wurden (siehe {@link PayloadReadResult}). Leer heisst „nichts ersetzt".
85
+ */
86
+ substitutedFields: string[];
87
+ }
88
+ /** Baut aus einem Speicherpunkt einen Kandidaten oder nennt den Grund. */
89
+ export declare function candidateFromPoint(point: ScoredPointV1): {
90
+ ok: true;
91
+ candidate: SearchCandidate;
92
+ } | {
93
+ ok: false;
94
+ reason: string;
95
+ };
96
+ /** Liest ein zusaetzliches Zahlenfeld aus dem rohen Payload (z. B. `changed_at_epoch_ms`). */
97
+ export declare function readRawNumber(raw: Record<string, unknown>, key: string): number | undefined;
98
+ /** Liest ein zusaetzliches Textfeld aus dem rohen Payload (z. B. `generation_id`). */
99
+ export declare function readRawString(raw: Record<string, unknown>, key: string): string | undefined;
100
+ /**
101
+ * Der Text, gegen den der lexikalische Zweig rankt. Bewusst mehr als nur der
102
+ * Inhalt: Pfad und Symbolnamen gehoeren zum Suchgegenstand, sonst findet
103
+ * „PaymentService charge" den Treffer nur, wenn beide Woerter zufaellig im
104
+ * Rumpf stehen (spec.md §8.6 nennt fuer den BM25-Text genau diese Bestand-
105
+ * teile: Code, Pfad, Symbolnamen, Bezeichner).
106
+ */
107
+ export declare function lexicalDocumentText(payload: CodeChunkPayloadV1): string;
108
+ //# sourceMappingURL=payload.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"payload.d.ts","sourceRoot":"","sources":["../src/payload.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,EAAE,kBAAkB,EAAgB,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAiB7F;;;;;;;;;GASG;AACH,MAAM,MAAM,iBAAiB,GACzB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,kBAAkB,CAAC;IAAC,iBAAiB,EAAE,MAAM,EAAE,CAAA;CAAE,GACtE;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAYlC;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAAG,iBAAiB,CA8FhG;AAmID;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,kCAAkC;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,kBAAkB,CAAC;IAC5B;;;;;OAKG;IACH,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC7B,4EAA4E;IAC5E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yCAAyC;IACzC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4EAA4E;IAC5E,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,+CAA+C;IAC/C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iEAAiE;IACjE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,4EAA4E;IAC5E,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,uEAAuE;IACvE,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B;;;OAGG;IACH,iBAAiB,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED,0EAA0E;AAC1E,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,aAAa,GACnB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,SAAS,EAAE,eAAe,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAc1E;AAED,8FAA8F;AAC9F,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAG3F;AAED,sFAAsF;AACtF,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAG3F;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,kBAAkB,GAAG,MAAM,CASvE"}
@@ -0,0 +1,263 @@
1
+ import { sortByCodepoints } from "@untangle-code/domain";
2
+ /** Pflichtfelder, ohne die ein Treffer keine belastbare Provenienz hat. */
3
+ const REQUIRED_STRING_FIELDS = [
4
+ "point_type",
5
+ "workspace_id",
6
+ "repo_id",
7
+ "ref_id",
8
+ "file_id",
9
+ "file_path",
10
+ "chunk_id",
11
+ "metrics_scope_id",
12
+ ];
13
+ const PARSE_QUALITIES = ["complete", "partial", "failed"];
14
+ function readString(record, key) {
15
+ const value = record[key];
16
+ return typeof value === "string" ? value : undefined;
17
+ }
18
+ function readNumber(record, key) {
19
+ const value = record[key];
20
+ return typeof value === "number" && Number.isFinite(value) ? value : undefined;
21
+ }
22
+ /**
23
+ * Prueft einen rohen Payload auf die Felder, die der Abrufkern braucht, und
24
+ * fuellt fehlende OPTIONALE Felder mit dokumentierten Ersatzwerten:
25
+ * `repo_label` faellt auf `repo_id` zurueck, `ref_name` auf `ref_id`,
26
+ * `language` auf `"unknown"`, `parse_quality` auf `"failed"` (nicht auf
27
+ * `"complete"` — eine unbekannte Parsequalitaet als vollstaendig auszugeben
28
+ * waere genau die stille Beschoenigung, die BUILD_PLAN E4 verbietet).
29
+ *
30
+ * JEDER dieser Ersatzwerte wird in `substitutedFields` genannt. Der Aufrufer
31
+ * traegt die Liste weiter (`SearchHitV1.incompletePayloadFields`), damit ein
32
+ * Leser den geratenen Wert vom gespeicherten unterscheiden kann.
33
+ *
34
+ * Der BEREICH ist davon ausgenommen: ein fehlendes `end_line` faellt auf
35
+ * `start_line` zurueck, ein fehlendes `end_byte` auf `start_byte` — nie auf 0,
36
+ * denn ein `SourceRange` mit `endByte < startByte` ist nicht ungenau, sondern
37
+ * UNGUELTIG; wer damit eine Datei aufschneidet, bekommt die falsche Stelle.
38
+ * Ist ein Bereich im gespeicherten Payload selbst ungueltig, wird der Punkt
39
+ * abgelehnt statt zurechtgebogen.
40
+ */
41
+ export function readCodeChunkPayload(raw) {
42
+ if (raw === undefined) {
43
+ return { ok: false, reason: "point carries no payload (query ran with withPayload=false?)" };
44
+ }
45
+ const missing = REQUIRED_STRING_FIELDS.filter((field) => readString(raw, field) === undefined);
46
+ if (missing.length > 0) {
47
+ return { ok: false, reason: `payload is missing required field(s): ${missing.join(", ")}` };
48
+ }
49
+ const pointType = readString(raw, "point_type");
50
+ if (pointType !== "code_chunk") {
51
+ return { ok: false, reason: `payload point_type is "${pointType}", expected "code_chunk"` };
52
+ }
53
+ const substituted = [];
54
+ const parseQualityRaw = readString(raw, "parse_quality");
55
+ const parseQuality = PARSE_QUALITIES.includes(parseQualityRaw)
56
+ ? parseQualityRaw
57
+ : "failed";
58
+ if (parseQualityRaw === undefined || parseQuality !== parseQualityRaw) {
59
+ substituted.push("parse_quality");
60
+ }
61
+ const repoId = readString(raw, "repo_id");
62
+ const refId = readString(raw, "ref_id");
63
+ const range = readSourceRange(raw, substituted);
64
+ if (!range.ok) {
65
+ return { ok: false, reason: range.reason };
66
+ }
67
+ const { startLine, endLine, startByte, endByte } = range;
68
+ // Pflichtfelder zuerst, Optionale danach EINZELN zuweisen: eine Kette aus
69
+ // bedingten Spreads erzeugt unter `exactOptionalPropertyTypes` einen
70
+ // Uniontyp, den der Compiler ab etwa einem Dutzend Feldern nicht mehr
71
+ // darstellen kann (TS2590). Die Zuweisungsform ist ausserdem leichter zu
72
+ // lesen und laesst keinen Zweifel, welches Feld optional ist.
73
+ const payload = {
74
+ schema_version: 1,
75
+ point_type: "code_chunk",
76
+ workspace_id: readString(raw, "workspace_id"),
77
+ repo_id: repoId,
78
+ repo_label: stringOrSubstitute(raw, "repo_label", repoId, substituted),
79
+ ref_id: refId,
80
+ ref_name: stringOrSubstitute(raw, "ref_name", refId, substituted),
81
+ file_id: readString(raw, "file_id"),
82
+ file_path: readString(raw, "file_path"),
83
+ file_hash: stringOrSubstitute(raw, "file_hash", "", substituted),
84
+ language: stringOrSubstitute(raw, "language", "unknown", substituted),
85
+ parse_quality: parseQuality,
86
+ chunk_id: readString(raw, "chunk_id"),
87
+ chunk_kind: stringOrSubstitute(raw, "chunk_kind", "fallback_lines", substituted),
88
+ chunk_ordinal: numberOrSubstitute(raw, "chunk_ordinal", 0, substituted),
89
+ start_line: startLine,
90
+ end_line: endLine,
91
+ start_byte: startByte,
92
+ end_byte: endByte,
93
+ content: stringOrSubstitute(raw, "content", "", substituted),
94
+ content_hash: stringOrSubstitute(raw, "content_hash", "", substituted),
95
+ parser_version: stringOrSubstitute(raw, "parser_version", "", substituted),
96
+ chunker_version: stringOrSubstitute(raw, "chunker_version", "", substituted),
97
+ metrics_version: stringOrSubstitute(raw, "metrics_version", "unknown", substituted),
98
+ embedding_profile_id: stringOrSubstitute(raw, "embedding_profile_id", "", substituted),
99
+ // Altindizes bleiben lesbar, aber der Ersatz steht sichtbar im
100
+ // Unvollstaendigkeitsledger. Fuer die echte Trefferprovenienz liest der
101
+ // Abrufkern weiterhin das unveraenderte `raw`-Objekt; "unknown" wird
102
+ // dadurch nie als gespeicherte Generation ausgegeben.
103
+ generation_id: stringOrSubstitute(raw, "generation_id", "unknown", substituted),
104
+ embedding_truncated: raw["embedding_truncated"] === true,
105
+ metrics_scope: stringOrSubstitute(raw, "metrics_scope", "chunk", substituted),
106
+ metrics_scope_id: readString(raw, "metrics_scope_id"),
107
+ };
108
+ assignOptionalString(payload, "commit_sha", readString(raw, "commit_sha"));
109
+ assignOptionalString(payload, "symbol_id", readString(raw, "symbol_id"));
110
+ assignOptionalString(payload, "symbol_name", readString(raw, "symbol_name"));
111
+ assignOptionalString(payload, "symbol_fqn", readString(raw, "symbol_fqn"));
112
+ assignOptionalString(payload, "symbol_kind", readString(raw, "symbol_kind"));
113
+ assignOptionalString(payload, "signature", readString(raw, "signature"));
114
+ assignOptionalString(payload, "ast_hash", readString(raw, "ast_hash"));
115
+ assignOptionalNumber(payload, "fragment_index", readNumber(raw, "fragment_index"));
116
+ assignOptionalNumber(payload, "fragment_count", readNumber(raw, "fragment_count"));
117
+ assignOptionalNumber(payload, "cyclomatic_classic", readNumber(raw, "cyclomatic_classic"));
118
+ assignOptionalNumber(payload, "cyclomatic_extended", readNumber(raw, "cyclomatic_extended"));
119
+ assignOptionalNumber(payload, "cognitive", readNumber(raw, "cognitive"));
120
+ assignOptionalNumber(payload, "max_nesting", readNumber(raw, "max_nesting"));
121
+ assignOptionalNumber(payload, "sloc", readNumber(raw, "sloc"));
122
+ assignOptionalNumber(payload, "halstead_volume", readNumber(raw, "halstead_volume"));
123
+ assignOptionalNumber(payload, "maintainability_index", readNumber(raw, "maintainability_index"));
124
+ assignOptionalNumber(payload, "risk_score", readNumber(raw, "risk_score"));
125
+ return { ok: true, payload, substitutedFields: sortByCodepoints(substituted) };
126
+ }
127
+ /**
128
+ * Liest den Quellbereich und lehnt einen ungueltigen ab.
129
+ *
130
+ * Fehlende Enden werden auf den ANFANG gesetzt (leerer, aber gueltiger
131
+ * Bereich) und gemeldet; ein gespeichertes Ende VOR dem Anfang ist dagegen
132
+ * kaputte Provenienz und wird nicht stillschweigend repariert.
133
+ */
134
+ function readSourceRange(raw, substituted) {
135
+ const startLine = numberOrSubstitute(raw, "start_line", 1, substituted);
136
+ const startByte = numberOrSubstitute(raw, "start_byte", 0, substituted);
137
+ const endLine = numberOrSubstitute(raw, "end_line", startLine, substituted);
138
+ const endByte = numberOrSubstitute(raw, "end_byte", startByte, substituted);
139
+ // WP-191: „nicht ganzzahlig" und „liegt vor dem Anfang" sind ZWEI Befunde,
140
+ // und der Ledger nennt den, der wirklich zutrifft. Zusammengefasst meldete
141
+ // ein `end_line` von 12.5 bei `start_line` 3 „12.5 is before start_line 3" —
142
+ // eine Begruendung, die der Zahl offen widerspricht. Wer so etwas liest,
143
+ // sucht den Fehler an der falschen Stelle, und genau dafuer ist ein Ledger
144
+ // nicht da.
145
+ if (!Number.isInteger(startLine)) {
146
+ return {
147
+ ok: false,
148
+ reason: `payload has a non-integer start_line (${startLine}); line numbers are whole numbers`,
149
+ };
150
+ }
151
+ if (startLine < 1) {
152
+ return {
153
+ ok: false,
154
+ reason: `payload has an invalid start_line (${startLine}); lines are 1-based`,
155
+ };
156
+ }
157
+ if (!Number.isInteger(startByte)) {
158
+ return {
159
+ ok: false,
160
+ reason: `payload has a non-integer start_byte (${startByte}); byte offsets are whole numbers`,
161
+ };
162
+ }
163
+ if (startByte < 0) {
164
+ return { ok: false, reason: `payload has an invalid start_byte (${startByte})` };
165
+ }
166
+ if (!Number.isInteger(endLine)) {
167
+ return {
168
+ ok: false,
169
+ reason: `payload has a non-integer end_line (${endLine}); line numbers are whole numbers`,
170
+ };
171
+ }
172
+ if (endLine < startLine) {
173
+ return {
174
+ ok: false,
175
+ reason: `payload has an invalid source range: end_line ${endLine} is before start_line ${startLine}`,
176
+ };
177
+ }
178
+ if (!Number.isInteger(endByte)) {
179
+ return {
180
+ ok: false,
181
+ reason: `payload has a non-integer end_byte (${endByte}); byte offsets are whole numbers`,
182
+ };
183
+ }
184
+ if (endByte < startByte) {
185
+ return {
186
+ ok: false,
187
+ reason: `payload has an invalid source range: end_byte ${endByte} is before start_byte ${startByte}`,
188
+ };
189
+ }
190
+ return { ok: true, startLine, endLine, startByte, endByte };
191
+ }
192
+ /** Liest ein Textfeld oder nennt den Ersatzwert beim Namen. */
193
+ function stringOrSubstitute(raw, key, fallback, substituted) {
194
+ const value = readString(raw, key);
195
+ if (value === undefined) {
196
+ substituted.push(key);
197
+ return fallback;
198
+ }
199
+ return value;
200
+ }
201
+ /** Liest ein Zahlenfeld oder nennt den Ersatzwert beim Namen. */
202
+ function numberOrSubstitute(raw, key, fallback, substituted) {
203
+ const value = readNumber(raw, key);
204
+ if (value === undefined) {
205
+ substituted.push(key);
206
+ return fallback;
207
+ }
208
+ return value;
209
+ }
210
+ function assignOptionalString(payload, key, value) {
211
+ if (value !== undefined) {
212
+ payload[key] = value;
213
+ }
214
+ }
215
+ function assignOptionalNumber(payload, key, value) {
216
+ if (value !== undefined) {
217
+ payload[key] = value;
218
+ }
219
+ }
220
+ /** Baut aus einem Speicherpunkt einen Kandidaten oder nennt den Grund. */
221
+ export function candidateFromPoint(point) {
222
+ const read = readCodeChunkPayload(point.payload);
223
+ if (!read.ok) {
224
+ return { ok: false, reason: read.reason };
225
+ }
226
+ return {
227
+ ok: true,
228
+ candidate: {
229
+ pointId: point.id,
230
+ payload: read.payload,
231
+ raw: point.payload ?? {},
232
+ substitutedFields: read.substitutedFields,
233
+ },
234
+ };
235
+ }
236
+ /** Liest ein zusaetzliches Zahlenfeld aus dem rohen Payload (z. B. `changed_at_epoch_ms`). */
237
+ export function readRawNumber(raw, key) {
238
+ const value = raw[key];
239
+ return typeof value === "number" && Number.isFinite(value) ? value : undefined;
240
+ }
241
+ /** Liest ein zusaetzliches Textfeld aus dem rohen Payload (z. B. `generation_id`). */
242
+ export function readRawString(raw, key) {
243
+ const value = raw[key];
244
+ return typeof value === "string" && value !== "" ? value : undefined;
245
+ }
246
+ /**
247
+ * Der Text, gegen den der lexikalische Zweig rankt. Bewusst mehr als nur der
248
+ * Inhalt: Pfad und Symbolnamen gehoeren zum Suchgegenstand, sonst findet
249
+ * „PaymentService charge" den Treffer nur, wenn beide Woerter zufaellig im
250
+ * Rumpf stehen (spec.md §8.6 nennt fuer den BM25-Text genau diese Bestand-
251
+ * teile: Code, Pfad, Symbolnamen, Bezeichner).
252
+ */
253
+ export function lexicalDocumentText(payload) {
254
+ const parts = [
255
+ payload.file_path,
256
+ payload.symbol_name ?? "",
257
+ payload.symbol_fqn ?? "",
258
+ payload.signature ?? "",
259
+ payload.content,
260
+ ];
261
+ return parts.filter((part) => part !== "").join("\n");
262
+ }
263
+ //# sourceMappingURL=payload.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"payload.js","sourceRoot":"","sources":["../src/payload.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEzD,2EAA2E;AAC3E,MAAM,sBAAsB,GAAG;IAC7B,YAAY;IACZ,cAAc;IACd,SAAS;IACT,QAAQ;IACR,SAAS;IACT,WAAW;IACX,UAAU;IACV,kBAAkB;CACV,CAAC;AAEX,MAAM,eAAe,GAA4B,CAAC,UAAU,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;AAgBnF,SAAS,UAAU,CAAC,MAA+B,EAAE,GAAW;IAC9D,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IAC1B,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AACvD,CAAC;AAED,SAAS,UAAU,CAAC,MAA+B,EAAE,GAAW;IAC9D,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IAC1B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AACjF,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,oBAAoB,CAAC,GAAwC;IAC3E,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACtB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,8DAA8D,EAAE,CAAC;IAC/F,CAAC;IACD,MAAM,OAAO,GAAG,sBAAsB,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,KAAK,SAAS,CAAC,CAAC;IAC/F,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,yCAAyC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;IAC9F,CAAC;IACD,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE,YAAY,CAAW,CAAC;IAC1D,IAAI,SAAS,KAAK,YAAY,EAAE,CAAC;QAC/B,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,0BAA0B,SAAS,0BAA0B,EAAE,CAAC;IAC9F,CAAC;IACD,MAAM,WAAW,GAAa,EAAE,CAAC;IACjC,MAAM,eAAe,GAAG,UAAU,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;IACzD,MAAM,YAAY,GAAiB,eAAe,CAAC,QAAQ,CAAC,eAA+B,CAAC;QAC1F,CAAC,CAAE,eAAgC;QACnC,CAAC,CAAC,QAAQ,CAAC;IACb,IAAI,eAAe,KAAK,SAAS,IAAI,YAAY,KAAK,eAAe,EAAE,CAAC;QACtE,WAAW,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IACpC,CAAC;IACD,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,EAAE,SAAS,CAAW,CAAC;IACpD,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,QAAQ,CAAW,CAAC;IAElD,MAAM,KAAK,GAAG,eAAe,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;IAChD,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;QACd,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC;IAC7C,CAAC;IACD,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC;IAEzD,0EAA0E;IAC1E,qEAAqE;IACrE,sEAAsE;IACtE,yEAAyE;IACzE,8DAA8D;IAC9D,MAAM,OAAO,GAAuB;QAClC,cAAc,EAAE,CAAC;QACjB,UAAU,EAAE,YAAY;QACxB,YAAY,EAAE,UAAU,CAAC,GAAG,EAAE,cAAc,CAAW;QACvD,OAAO,EAAE,MAAM;QACf,UAAU,EAAE,kBAAkB,CAAC,GAAG,EAAE,YAAY,EAAE,MAAM,EAAE,WAAW,CAAC;QACtE,MAAM,EAAE,KAAK;QACb,QAAQ,EAAE,kBAAkB,CAAC,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,WAAW,CAAC;QACjE,OAAO,EAAE,UAAU,CAAC,GAAG,EAAE,SAAS,CAAW;QAC7C,SAAS,EAAE,UAAU,CAAC,GAAG,EAAE,WAAW,CAAW;QACjD,SAAS,EAAE,kBAAkB,CAAC,GAAG,EAAE,WAAW,EAAE,EAAE,EAAE,WAAW,CAAC;QAChE,QAAQ,EAAE,kBAAkB,CAAC,GAAG,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,CAAC;QACrE,aAAa,EAAE,YAAY;QAC3B,QAAQ,EAAE,UAAU,CAAC,GAAG,EAAE,UAAU,CAAW;QAC/C,UAAU,EAAE,kBAAkB,CAAC,GAAG,EAAE,YAAY,EAAE,gBAAgB,EAAE,WAAW,CAAC;QAChF,aAAa,EAAE,kBAAkB,CAAC,GAAG,EAAE,eAAe,EAAE,CAAC,EAAE,WAAW,CAAC;QACvE,UAAU,EAAE,SAAS;QACrB,QAAQ,EAAE,OAAO;QACjB,UAAU,EAAE,SAAS;QACrB,QAAQ,EAAE,OAAO;QACjB,OAAO,EAAE,kBAAkB,CAAC,GAAG,EAAE,SAAS,EAAE,EAAE,EAAE,WAAW,CAAC;QAC5D,YAAY,EAAE,kBAAkB,CAAC,GAAG,EAAE,cAAc,EAAE,EAAE,EAAE,WAAW,CAAC;QACtE,cAAc,EAAE,kBAAkB,CAAC,GAAG,EAAE,gBAAgB,EAAE,EAAE,EAAE,WAAW,CAAC;QAC1E,eAAe,EAAE,kBAAkB,CAAC,GAAG,EAAE,iBAAiB,EAAE,EAAE,EAAE,WAAW,CAAC;QAC5E,eAAe,EAAE,kBAAkB,CAAC,GAAG,EAAE,iBAAiB,EAAE,SAAS,EAAE,WAAW,CAAC;QACnF,oBAAoB,EAAE,kBAAkB,CAAC,GAAG,EAAE,sBAAsB,EAAE,EAAE,EAAE,WAAW,CAAC;QACtF,+DAA+D;QAC/D,wEAAwE;QACxE,qEAAqE;QACrE,sDAAsD;QACtD,aAAa,EAAE,kBAAkB,CAAC,GAAG,EAAE,eAAe,EAAE,SAAS,EAAE,WAAW,CAAC;QAC/E,mBAAmB,EAAE,GAAG,CAAC,qBAAqB,CAAC,KAAK,IAAI;QACxD,aAAa,EAAE,kBAAkB,CAC/B,GAAG,EACH,eAAe,EACf,OAAO,EACP,WAAW,CAC2B;QACxC,gBAAgB,EAAE,UAAU,CAAC,GAAG,EAAE,kBAAkB,CAAW;KAChE,CAAC;IAEF,oBAAoB,CAAC,OAAO,EAAE,YAAY,EAAE,UAAU,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC,CAAC;IAC3E,oBAAoB,CAAC,OAAO,EAAE,WAAW,EAAE,UAAU,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC,CAAC;IACzE,oBAAoB,CAAC,OAAO,EAAE,aAAa,EAAE,UAAU,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC,CAAC;IAC7E,oBAAoB,CAAC,OAAO,EAAE,YAAY,EAAE,UAAU,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC,CAAC;IAC3E,oBAAoB,CAAC,OAAO,EAAE,aAAa,EAAE,UAAU,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC,CAAC;IAC7E,oBAAoB,CAAC,OAAO,EAAE,WAAW,EAAE,UAAU,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC,CAAC;IACzE,oBAAoB,CAAC,OAAO,EAAE,UAAU,EAAE,UAAU,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC,CAAC;IACvE,oBAAoB,CAAC,OAAO,EAAE,gBAAgB,EAAE,UAAU,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAC,CAAC;IACnF,oBAAoB,CAAC,OAAO,EAAE,gBAAgB,EAAE,UAAU,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAC,CAAC;IACnF,oBAAoB,CAAC,OAAO,EAAE,oBAAoB,EAAE,UAAU,CAAC,GAAG,EAAE,oBAAoB,CAAC,CAAC,CAAC;IAC3F,oBAAoB,CAAC,OAAO,EAAE,qBAAqB,EAAE,UAAU,CAAC,GAAG,EAAE,qBAAqB,CAAC,CAAC,CAAC;IAC7F,oBAAoB,CAAC,OAAO,EAAE,WAAW,EAAE,UAAU,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC,CAAC;IACzE,oBAAoB,CAAC,OAAO,EAAE,aAAa,EAAE,UAAU,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC,CAAC;IAC7E,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC;IAC/D,oBAAoB,CAAC,OAAO,EAAE,iBAAiB,EAAE,UAAU,CAAC,GAAG,EAAE,iBAAiB,CAAC,CAAC,CAAC;IACrF,oBAAoB,CAAC,OAAO,EAAE,uBAAuB,EAAE,UAAU,CAAC,GAAG,EAAE,uBAAuB,CAAC,CAAC,CAAC;IACjG,oBAAoB,CAAC,OAAO,EAAE,YAAY,EAAE,UAAU,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC,CAAC;IAE3E,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,CAAC,WAAW,CAAC,EAAE,CAAC;AACjF,CAAC;AAED;;;;;;GAMG;AACH,SAAS,eAAe,CACtB,GAA4B,EAC5B,WAAqB;IAIrB,MAAM,SAAS,GAAG,kBAAkB,CAAC,GAAG,EAAE,YAAY,EAAE,CAAC,EAAE,WAAW,CAAC,CAAC;IACxE,MAAM,SAAS,GAAG,kBAAkB,CAAC,GAAG,EAAE,YAAY,EAAE,CAAC,EAAE,WAAW,CAAC,CAAC;IACxE,MAAM,OAAO,GAAG,kBAAkB,CAAC,GAAG,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;IAC5E,MAAM,OAAO,GAAG,kBAAkB,CAAC,GAAG,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;IAC5E,2EAA2E;IAC3E,2EAA2E;IAC3E,6EAA6E;IAC7E,yEAAyE;IACzE,2EAA2E;IAC3E,YAAY;IACZ,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,CAAC;QACjC,OAAO;YACL,EAAE,EAAE,KAAK;YACT,MAAM,EAAE,yCAAyC,SAAS,mCAAmC;SAC9F,CAAC;IACJ,CAAC;IACD,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;QAClB,OAAO;YACL,EAAE,EAAE,KAAK;YACT,MAAM,EAAE,sCAAsC,SAAS,sBAAsB;SAC9E,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,CAAC;QACjC,OAAO;YACL,EAAE,EAAE,KAAK;YACT,MAAM,EAAE,yCAAyC,SAAS,mCAAmC;SAC9F,CAAC;IACJ,CAAC;IACD,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;QAClB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,sCAAsC,SAAS,GAAG,EAAE,CAAC;IACnF,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;QAC/B,OAAO;YACL,EAAE,EAAE,KAAK;YACT,MAAM,EAAE,uCAAuC,OAAO,mCAAmC;SAC1F,CAAC;IACJ,CAAC;IACD,IAAI,OAAO,GAAG,SAAS,EAAE,CAAC;QACxB,OAAO;YACL,EAAE,EAAE,KAAK;YACT,MAAM,EAAE,iDAAiD,OAAO,yBAAyB,SAAS,EAAE;SACrG,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;QAC/B,OAAO;YACL,EAAE,EAAE,KAAK;YACT,MAAM,EAAE,uCAAuC,OAAO,mCAAmC;SAC1F,CAAC;IACJ,CAAC;IACD,IAAI,OAAO,GAAG,SAAS,EAAE,CAAC;QACxB,OAAO;YACL,EAAE,EAAE,KAAK;YACT,MAAM,EAAE,iDAAiD,OAAO,yBAAyB,SAAS,EAAE;SACrG,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC;AAC9D,CAAC;AAED,+DAA+D;AAC/D,SAAS,kBAAkB,CACzB,GAA4B,EAC5B,GAAW,EACX,QAAgB,EAChB,WAAqB;IAErB,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACnC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACtB,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,iEAAiE;AACjE,SAAS,kBAAkB,CACzB,GAA4B,EAC5B,GAAW,EACX,QAAgB,EAChB,WAAqB;IAErB,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACnC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACtB,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAUD,SAAS,oBAAoB,CAC3B,OAA2B,EAC3B,GAAsB,EACtB,KAAyB;IAEzB,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACvB,OAA8C,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IAC/D,CAAC;AACH,CAAC;AAED,SAAS,oBAAoB,CAC3B,OAA2B,EAC3B,GAAsB,EACtB,KAAyB;IAEzB,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACvB,OAA8C,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IAC/D,CAAC;AACH,CAAC;AAsCD,0EAA0E;AAC1E,MAAM,UAAU,kBAAkB,CAChC,KAAoB;IAEpB,MAAM,IAAI,GAAG,oBAAoB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACjD,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;QACb,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC;IAC5C,CAAC;IACD,OAAO;QACL,EAAE,EAAE,IAAI;QACR,SAAS,EAAE;YACT,OAAO,EAAE,KAAK,CAAC,EAAE;YACjB,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,GAAG,EAAE,KAAK,CAAC,OAAO,IAAI,EAAE;YACxB,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;SAC1C;KACF,CAAC;AACJ,CAAC;AAED,8FAA8F;AAC9F,MAAM,UAAU,aAAa,CAAC,GAA4B,EAAE,GAAW;IACrE,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;IACvB,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AACjF,CAAC;AAED,sFAAsF;AACtF,MAAM,UAAU,aAAa,CAAC,GAA4B,EAAE,GAAW;IACrE,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;IACvB,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AACvE,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAA2B;IAC7D,MAAM,KAAK,GAAG;QACZ,OAAO,CAAC,SAAS;QACjB,OAAO,CAAC,WAAW,IAAI,EAAE;QACzB,OAAO,CAAC,UAAU,IAAI,EAAE;QACxB,OAAO,CAAC,SAAS,IAAI,EAAE;QACvB,OAAO,CAAC,OAAO;KAChB,CAAC;IACF,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACxD,CAAC"}
package/dist/port.d.ts ADDED
@@ -0,0 +1,112 @@
1
+ /**
2
+ * Der Port des Abrufkerns.
3
+ *
4
+ * Er ist bewusst so geschnitten, dass er OHNE laufendes Qdrant vollstaendig
5
+ * testbar ist: alles, was Infrastruktur braucht, steckt hinter zwei bereits
6
+ * bestehenden Domain-Ports (`VectorStore`, `EmbeddingProvider`) plus einer
7
+ * kleinen, injizierbaren Funktion fuer die spaerliche Vektorisierung. Die
8
+ * Kontraktsuite in `testing/search-port.contract.ts` laeuft deshalb unveraendert
9
+ * gegen den In-Memory-Speicher des testkits und spaeter gegen den echten
10
+ * Qdrant-Adapter — dieselbe Bauart wie `runVectorStoreContract`.
11
+ *
12
+ * Ausdruecklich NICHT Teil des Ports: Collection-Namen. Welche Collection zu
13
+ * welchem Embedding-Profil gehoert, entscheidet der Adapter (spec.md §10.1);
14
+ * der Abrufkern bekommt die fertige Zuordnung als {@link ProfileTargetV1}
15
+ * gereicht. Damit kennt dieses Paket kein Qdrant-Detail.
16
+ */
17
+ import type { EmbeddingProvider, FindabilitySummaryV1, PortCallOptions, SearchGraphRelationsV1, SearchResultSetV1, SparseVectorV1, ToolWarningV1 } from "@untangle-code/domain";
18
+ import type { GrepRequestV1, GrepResultSetV1, UntangleSearchRequestV1 } from "./types.js";
19
+ /**
20
+ * Ein Suchziel: genau ein Embedding-Profil, genau eine Collection, die
21
+ * Repositories, die darin liegen.
22
+ *
23
+ * Mehrere Ziele heissen mehrere Ergebnisgruppen (spec.md §13.4): Scores
24
+ * verschiedener Profile werden NIE in eine gemeinsame absolute Rangfolge
25
+ * gemischt.
26
+ */
27
+ export interface ProfileTargetV1 {
28
+ embeddingProfileId: string;
29
+ /** Name der Collection im Vektorspeicher. */
30
+ collection: string;
31
+ /** Repositories, die zu dieser Collection beitragen. */
32
+ repoIds: string[];
33
+ /** Der Embedder dieses Profils; erzeugt das Query-Embedding. */
34
+ embedder: EmbeddingProvider;
35
+ /** Lokal bekannte Generationen je Repo/Ref samt Abschlussstatus als Provenienz. */
36
+ indexContexts?: readonly {
37
+ repoId: string;
38
+ refId: string;
39
+ generationId: string;
40
+ /** Immutable manifest fingerprint for this completed corpus snapshot. */
41
+ corpusRevisionFingerprint?: string;
42
+ outcome: "running" | "completed" | "cancelled" | "failed";
43
+ }[];
44
+ }
45
+ /**
46
+ * Erzeugt den spaerlichen Vektor einer Anfrage fuer den Abruf im Speicher.
47
+ *
48
+ * Die Funktion MUSS dieselbe Tokenisierung und Hashbildung verwenden wie der
49
+ * Indexlauf, sonst treffen Anfrage- und Dokumentvektor sich nicht. Genau
50
+ * deshalb ist sie injiziert und nicht hier implementiert: sie gehoert zum
51
+ * Speicheradapter, nicht zum Abrufkern.
52
+ *
53
+ * Fehlt sie, ist der lexikalische Abrufzweig nicht ausfuehrbar. Hybrid kann
54
+ * ueber Dense und Symbolnamen sichtbar degradiert antworten; reine
55
+ * lexikalische Suche meldet einen Fehler. Der BM25-Rang wird weiterhin in
56
+ * diesem Paket berechnet (`bm25.ts`).
57
+ */
58
+ export type SparseVectorizer = (text: string) => SparseVectorV1;
59
+ /** Liefert die Findability eines Symbols, sofern sie berechnet wurde. */
60
+ export type FindabilityLookup = (symbolId: string) => FindabilitySummaryV1 | undefined;
61
+ /** Liefert die Graph-Naehe eines Symbols zur Anfrage, in [0, 1]. */
62
+ export type GraphProximityLookup = (symbolId: string) => number | undefined;
63
+ /** Ein bereits final gerankter Treffer, den ein Graphadapter anreichern darf. */
64
+ export interface SearchGraphEnrichmentTargetV1 {
65
+ /** Nur innerhalb eines Aufrufs eindeutig; wird unveraendert zurueckgegeben. */
66
+ targetId: string;
67
+ workspaceId: string;
68
+ generationId: string;
69
+ repoId: string;
70
+ refId: string;
71
+ fileId: string;
72
+ filePath: string;
73
+ symbolId?: string;
74
+ }
75
+ /** Batch-Anfrage an den optionalen, graph-agnostischen Anreicherungsport. */
76
+ export interface SearchGraphEnrichmentRequestV1 {
77
+ includeContext: boolean;
78
+ includeLinked: boolean;
79
+ /** Harte Obergrenze je Treffer und Graphart. */
80
+ relationLimit: number;
81
+ /** Reihenfolge entspricht Gruppenreihenfolge und finalem Rang. */
82
+ targets: readonly SearchGraphEnrichmentTargetV1[];
83
+ }
84
+ /** Anreicherung genau eines finalen Treffers. */
85
+ export interface SearchGraphEnrichmentEntryV1 {
86
+ targetId: string;
87
+ graphContext?: SearchGraphRelationsV1;
88
+ linkedSymbols?: SearchGraphRelationsV1;
89
+ }
90
+ /** Batch-Ergebnis; Teilgraph-Ausfaelle bleiben als Warnungen und Facetten sichtbar. */
91
+ export interface SearchGraphEnrichmentResultV1 {
92
+ entries: readonly SearchGraphEnrichmentEntryV1[];
93
+ warnings: readonly ToolWarningV1[];
94
+ }
95
+ /**
96
+ * Schmale Grenze zum persistierten File-/Symbolgraphen. Das Search-Paket
97
+ * kennt weder deren Snapshottypen noch deren Speicherlayout.
98
+ */
99
+ export interface SearchGraphEnrichmentPort {
100
+ enrich(request: SearchGraphEnrichmentRequestV1, options?: PortCallOptions): Promise<SearchGraphEnrichmentResultV1>;
101
+ }
102
+ /**
103
+ * Der Abrufkern als Port: semantische Suche und grep-artige Suche unter EINER
104
+ * Oberflaeche (Nutzerwunsch A4).
105
+ */
106
+ export interface SearchPort {
107
+ /** Hybride Suche mit vollstaendiger Score-Zerlegung (spec.md §13). */
108
+ search(request: UntangleSearchRequestV1, options?: PortCallOptions): Promise<SearchResultSetV1>;
109
+ /** Regex-/Literalsuche ueber den indexierten Inhalt. */
110
+ grep(request: GrepRequestV1, options?: PortCallOptions): Promise<GrepResultSetV1>;
111
+ }
112
+ //# sourceMappingURL=port.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"port.d.ts","sourceRoot":"","sources":["../src/port.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,KAAK,EACV,iBAAiB,EACjB,oBAAoB,EACpB,eAAe,EACf,sBAAsB,EACtB,iBAAiB,EACjB,cAAc,EACd,aAAa,EACd,MAAM,uBAAuB,CAAC;AAE/B,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAE1F;;;;;;;GAOG;AACH,MAAM,WAAW,eAAe;IAC9B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,6CAA6C;IAC7C,UAAU,EAAE,MAAM,CAAC;IACnB,wDAAwD;IACxD,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,gEAAgE;IAChE,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,mFAAmF;IACnF,aAAa,CAAC,EAAE,SAAS;QACvB,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;QACd,YAAY,EAAE,MAAM,CAAC;QACrB,yEAAyE;QACzE,yBAAyB,CAAC,EAAE,MAAM,CAAC;QACnC,OAAO,EAAE,SAAS,GAAG,WAAW,GAAG,WAAW,GAAG,QAAQ,CAAC;KAC3D,EAAE,CAAC;CACL;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,cAAc,CAAC;AAEhE,yEAAyE;AACzE,MAAM,MAAM,iBAAiB,GAAG,CAAC,QAAQ,EAAE,MAAM,KAAK,oBAAoB,GAAG,SAAS,CAAC;AAEvF,oEAAoE;AACpE,MAAM,MAAM,oBAAoB,GAAG,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;AAE5E,iFAAiF;AACjF,MAAM,WAAW,6BAA6B;IAC5C,+EAA+E;IAC/E,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,6EAA6E;AAC7E,MAAM,WAAW,8BAA8B;IAC7C,cAAc,EAAE,OAAO,CAAC;IACxB,aAAa,EAAE,OAAO,CAAC;IACvB,gDAAgD;IAChD,aAAa,EAAE,MAAM,CAAC;IACtB,kEAAkE;IAClE,OAAO,EAAE,SAAS,6BAA6B,EAAE,CAAC;CACnD;AAED,iDAAiD;AACjD,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,sBAAsB,CAAC;IACtC,aAAa,CAAC,EAAE,sBAAsB,CAAC;CACxC;AAED,uFAAuF;AACvF,MAAM,WAAW,6BAA6B;IAC5C,OAAO,EAAE,SAAS,4BAA4B,EAAE,CAAC;IACjD,QAAQ,EAAE,SAAS,aAAa,EAAE,CAAC;CACpC;AAED;;;GAGG;AACH,MAAM,WAAW,yBAAyB;IACxC,MAAM,CACJ,OAAO,EAAE,8BAA8B,EACvC,OAAO,CAAC,EAAE,eAAe,GACxB,OAAO,CAAC,6BAA6B,CAAC,CAAC;CAC3C;AAED;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,sEAAsE;IACtE,MAAM,CAAC,OAAO,EAAE,uBAAuB,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAChG,wDAAwD;IACxD,IAAI,CAAC,OAAO,EAAE,aAAa,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;CACnF"}
package/dist/port.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=port.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"port.js","sourceRoot":"","sources":["../src/port.ts"],"names":[],"mappings":""}
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Task-basierte Search Journeys und Dynamic Product Complexity.
3
+ *
4
+ * Dieser Reducer ist I/O-agnostisch. Er speichert ausschliesslich ueber den
5
+ * Domain-Port, liest Zeit/Zufall ueber Ports und berechnet jede Kennzahl aus
6
+ * den persistierten Beobachtungen neu. Damit kann derselbe Ablauf lokal, im
7
+ * MCP-Server und in Tests identisch laufen.
8
+ */
9
+ import { type Clock, type DynamicProductComplexityReportV1, type DynamicSearchComplexityV1, type PortCallOptions, type Random, type SearchJourneyAttemptV1, type SearchJourneyAbandonReasonCode, type SearchJourneyExecutionContextInputV1, type SearchJourneyNavigationKind, type SearchJourneyStorePort, type SearchJourneyTargetV1, type SearchJourneyV1, type SearchResultSetV1 } from "@untangle-code/domain";
10
+ export declare const MINIMUM_PRODUCT_COMPLEXITY_SESSIONS = 3;
11
+ export declare const MAX_SEARCH_JOURNEY_ATTEMPTS = 128;
12
+ export declare const MAX_SEARCH_JOURNEY_FEATURE_ID_LENGTH = 256;
13
+ export declare const MAX_SEARCH_JOURNEY_NAVIGATION_EVENTS = 512;
14
+ interface SearchJourneyServiceBaseDeps {
15
+ workspaceId: string;
16
+ store: SearchJourneyStorePort;
17
+ clock: Clock;
18
+ random: Random;
19
+ }
20
+ /** Ein stabiler Key oder ein persistenter Provider ist fuer korrekte Wiederaufnahme zwingend. */
21
+ export type SearchJourneyServiceDeps = SearchJourneyServiceBaseDeps & ({
22
+ fingerprintKey: Uint8Array;
23
+ fingerprintKeyProvider?: never;
24
+ } | {
25
+ fingerprintKey?: never;
26
+ /** Lazy Variante, damit reine Leseoperationen keinen lokalen Schluessel anlegen. */
27
+ fingerprintKeyProvider: (options?: PortCallOptions) => Promise<Uint8Array>;
28
+ });
29
+ export interface StartSearchJourneyInput {
30
+ goal: string;
31
+ /** Stabile, vom Produkt vergebene Kennung fuer feature-uebergreifende Probevergleiche. */
32
+ featureId?: string;
33
+ /** Caller labels are pseudonymized by default; no automatic model or task inference. */
34
+ executionContext?: SearchJourneyExecutionContextInputV1;
35
+ /** Persistiert Ziel- und Querytext; Default false speichert nur Fingerprints. */
36
+ retainText?: boolean;
37
+ }
38
+ export interface ObserveSearchJourneyNavigationInput {
39
+ kind: SearchJourneyNavigationKind;
40
+ toolName?: string;
41
+ target?: SearchJourneyTargetV1;
42
+ }
43
+ export interface CompleteSearchJourneyInput {
44
+ target: SearchJourneyTargetV1;
45
+ /** Praezisiert den akzeptierten Versuch, wenn derselbe Treffer mehrfach vorkam. */
46
+ acceptedAttemptId?: string;
47
+ }
48
+ export interface RecordFailedSearchInput {
49
+ query: string;
50
+ failureCode: string;
51
+ failureReason: string;
52
+ }
53
+ export interface AbandonSearchJourneyInput {
54
+ /** Kontrollierter Grund, der auch im textfreien Default sicher gespeichert werden kann. */
55
+ reasonCode?: SearchJourneyAbandonReasonCode;
56
+ /** Freitext; wird nur bei einer mit `retainText` gestarteten Journey gespeichert. */
57
+ reason?: string;
58
+ }
59
+ export interface SearchJourneySearchLink {
60
+ /** 1-basierter, pro Session eindeutiger Schritt. */
61
+ step?: number;
62
+ }
63
+ export interface RecordedSearchAttempt {
64
+ session: SearchJourneyV1;
65
+ attempt: SearchJourneyAttemptV1;
66
+ }
67
+ /** Berechnet die erklaerbaren Komponenten einer abgeschlossenen Journey. */
68
+ export declare function assessSearchJourney(session: SearchJourneyV1, input: CompleteSearchJourneyInput): DynamicSearchComplexityV1;
69
+ /** Aggregiert ausschliesslich kompatible Messkontexte in getrennten Kohorten. */
70
+ export declare function buildDynamicProductComplexityReport(workspaceId: string, sessions: readonly SearchJourneyV1[], generatedAt: string): DynamicProductComplexityReportV1;
71
+ export declare class SearchJourneyService {
72
+ private readonly deps;
73
+ private readonly pendingMutations;
74
+ private fingerprintKey;
75
+ constructor(deps: SearchJourneyServiceDeps);
76
+ start(input: StartSearchJourneyInput, options?: PortCallOptions): Promise<SearchJourneyV1>;
77
+ get(sessionId: string, options?: PortCallOptions): Promise<SearchJourneyV1>;
78
+ recordSearch(sessionId: string, result: SearchResultSetV1, link?: SearchJourneySearchLink, options?: PortCallOptions): Promise<RecordedSearchAttempt>;
79
+ recordFailedSearch(sessionId: string, input: RecordFailedSearchInput, link?: SearchJourneySearchLink, options?: PortCallOptions): Promise<RecordedSearchAttempt>;
80
+ observeNavigation(sessionId: string, input: ObserveSearchJourneyNavigationInput, options?: PortCallOptions): Promise<SearchJourneyV1>;
81
+ complete(sessionId: string, input: CompleteSearchJourneyInput, options?: PortCallOptions): Promise<SearchJourneyV1>;
82
+ abandon(sessionId: string, input?: AbandonSearchJourneyInput, options?: PortCallOptions): Promise<SearchJourneyV1>;
83
+ report(options?: PortCallOptions): Promise<DynamicProductComplexityReportV1>;
84
+ private validatedFingerprintKey;
85
+ private getFingerprintKey;
86
+ private mutate;
87
+ }
88
+ export {};
89
+ //# sourceMappingURL=product-complexity.d.ts.map