@untangle-code/search 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +661 -0
- package/NOTICE +90 -0
- package/README.md +433 -2
- package/THIRD_PARTY_LICENSES.md +29 -0
- package/dist/benchmark-integrity.d.ts +12 -0
- package/dist/benchmark-integrity.d.ts.map +1 -0
- package/dist/benchmark-integrity.js +10 -0
- package/dist/benchmark-integrity.js.map +1 -0
- package/dist/bm25.d.ts +46 -0
- package/dist/bm25.d.ts.map +1 -0
- package/dist/bm25.js +105 -0
- package/dist/bm25.js.map +1 -0
- package/dist/deadline.d.ts +4 -0
- package/dist/deadline.d.ts.map +1 -0
- package/dist/deadline.js +54 -0
- package/dist/deadline.js.map +1 -0
- package/dist/dedupe.d.ts +48 -0
- package/dist/dedupe.d.ts.map +1 -0
- package/dist/dedupe.js +58 -0
- package/dist/dedupe.js.map +1 -0
- package/dist/diversify.d.ts +45 -0
- package/dist/diversify.d.ts.map +1 -0
- package/dist/diversify.js +30 -0
- package/dist/diversify.js.map +1 -0
- package/dist/engine.d.ts +157 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +1498 -0
- package/dist/engine.js.map +1 -0
- package/dist/enrichment.d.ts +16 -0
- package/dist/enrichment.d.ts.map +1 -0
- package/dist/enrichment.js +92 -0
- package/dist/enrichment.js.map +1 -0
- package/dist/filter.d.ts +86 -0
- package/dist/filter.d.ts.map +1 -0
- package/dist/filter.js +166 -0
- package/dist/filter.js.map +1 -0
- package/dist/findability.d.ts +144 -0
- package/dist/findability.d.ts.map +1 -0
- package/dist/findability.js +393 -0
- package/dist/findability.js.map +1 -0
- package/dist/format.d.ts +28 -0
- package/dist/format.d.ts.map +1 -0
- package/dist/format.js +172 -0
- package/dist/format.js.map +1 -0
- package/dist/fusion.d.ts +47 -0
- package/dist/fusion.d.ts.map +1 -0
- package/dist/fusion.js +84 -0
- package/dist/fusion.js.map +1 -0
- package/dist/glob.d.ts +50 -0
- package/dist/glob.d.ts.map +1 -0
- package/dist/glob.js +144 -0
- package/dist/glob.js.map +1 -0
- package/dist/grep.d.ts +76 -0
- package/dist/grep.d.ts.map +1 -0
- package/dist/grep.js +475 -0
- package/dist/grep.js.map +1 -0
- package/dist/index.d.ts +42 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +63 -0
- package/dist/index.js.map +1 -0
- package/dist/ledger.d.ts +45 -0
- package/dist/ledger.d.ts.map +1 -0
- package/dist/ledger.js +39 -0
- package/dist/ledger.js.map +1 -0
- package/dist/payload.d.ts +108 -0
- package/dist/payload.d.ts.map +1 -0
- package/dist/payload.js +263 -0
- package/dist/payload.js.map +1 -0
- package/dist/port.d.ts +112 -0
- package/dist/port.d.ts.map +1 -0
- package/dist/port.js +2 -0
- package/dist/port.js.map +1 -0
- package/dist/product-complexity.d.ts +89 -0
- package/dist/product-complexity.d.ts.map +1 -0
- package/dist/product-complexity.js +1367 -0
- package/dist/product-complexity.js.map +1 -0
- package/dist/regex-safety.d.ts +75 -0
- package/dist/regex-safety.d.ts.map +1 -0
- package/dist/regex-safety.js +902 -0
- package/dist/regex-safety.js.map +1 -0
- package/dist/relevance-prerequisites.d.ts +21 -0
- package/dist/relevance-prerequisites.d.ts.map +1 -0
- package/dist/relevance-prerequisites.js +47 -0
- package/dist/relevance-prerequisites.js.map +1 -0
- package/dist/relevance.d.ts +107 -0
- package/dist/relevance.d.ts.map +1 -0
- package/dist/relevance.js +199 -0
- package/dist/relevance.js.map +1 -0
- package/dist/retrieval.d.ts +46 -0
- package/dist/retrieval.d.ts.map +1 -0
- package/dist/retrieval.js +182 -0
- package/dist/retrieval.js.map +1 -0
- package/dist/scoring.d.ts +102 -0
- package/dist/scoring.d.ts.map +1 -0
- package/dist/scoring.js +175 -0
- package/dist/scoring.js.map +1 -0
- package/dist/sort.d.ts +21 -0
- package/dist/sort.d.ts.map +1 -0
- package/dist/sort.js +53 -0
- package/dist/sort.js.map +1 -0
- package/dist/symbol-match.d.ts +21 -0
- package/dist/symbol-match.d.ts.map +1 -0
- package/dist/symbol-match.js +72 -0
- package/dist/symbol-match.js.map +1 -0
- package/dist/tokenize.d.ts +41 -0
- package/dist/tokenize.d.ts.map +1 -0
- package/dist/tokenize.js +202 -0
- package/dist/tokenize.js.map +1 -0
- package/dist/types.d.ts +173 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +42 -0
- package/dist/types.js.map +1 -0
- package/package.json +61 -3
- package/src/benchmark-integrity.ts +25 -0
- package/src/bm25.ts +135 -0
- package/src/deadline.ts +59 -0
- package/src/dedupe.ts +99 -0
- package/src/diversify.ts +71 -0
- package/src/engine.ts +1957 -0
- package/src/enrichment.ts +115 -0
- package/src/filter.ts +267 -0
- package/src/findability.ts +580 -0
- package/src/format.ts +228 -0
- package/src/fusion.ts +121 -0
- package/src/glob.ts +151 -0
- package/src/grep.ts +618 -0
- package/src/index.ts +83 -0
- package/src/ledger.ts +72 -0
- package/src/payload.ts +382 -0
- package/src/port.ts +133 -0
- package/src/product-complexity.ts +2168 -0
- package/src/regex-safety.ts +1002 -0
- package/src/relevance-prerequisites.ts +83 -0
- package/src/relevance.ts +328 -0
- package/src/retrieval.ts +299 -0
- package/src/scoring.ts +321 -0
- package/src/sort.ts +86 -0
- package/src/symbol-match.ts +87 -0
- package/src/tokenize.ts +213 -0
- 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"}
|
package/dist/payload.js
ADDED
|
@@ -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":"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"}
|
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
package/dist/port.js.map
ADDED
|
@@ -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
|