@absolutejs/absolute 0.19.0-beta.525 → 0.19.0-beta.526
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/dist/ai/client/index.js +5 -5
- package/dist/ai/client/index.js.map +1 -1
- package/dist/ai/index.js +4 -4
- package/dist/ai/index.js.map +1 -1
- package/dist/ai-client/angular/ai/index.js +880 -862
- package/dist/ai-client/react/ai/index.js +24 -24
- package/dist/ai-client/vue/ai/index.js +21 -21
- package/dist/angular/ai/index.js +873 -855
- package/dist/angular/ai/index.js.map +7 -6
- package/dist/angular/index.js +2 -2
- package/dist/angular/index.js.map +1 -1
- package/dist/angular/server.js +2 -2
- package/dist/angular/server.js.map +1 -1
- package/dist/build.js +2 -2
- package/dist/build.js.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/react/ai/index.js +25 -25
- package/dist/react/ai/index.js.map +6 -6
- package/dist/src/ai/client/createRAGStream.d.ts +2 -0
- package/dist/src/ai/client/createRAGWorkflow.d.ts +3 -0
- package/dist/src/ai/client/index.d.ts +8 -7
- package/dist/src/ai/index.d.ts +5 -4
- package/dist/src/ai/rag/index.d.ts +2 -2
- package/dist/src/angular/ai/ai-rag-stream.service.d.ts +1 -1
- package/dist/src/angular/ai/ai-rag-workflow.service.d.ts +33 -0
- package/dist/src/angular/ai/index.d.ts +2 -1
- package/dist/src/react/ai/index.d.ts +6 -3
- package/dist/src/react/ai/useRAG.d.ts +3 -2
- package/dist/src/svelte/ai/createRAG.d.ts +5 -4
- package/dist/src/svelte/ai/createRAGStream.d.ts +1 -1
- package/dist/src/svelte/ai/createRAGStreamProgress.d.ts +1 -1
- package/dist/src/svelte/ai/createRAGWorkflow.d.ts +1 -1
- package/dist/src/svelte/ai/index.d.ts +4 -2
- package/dist/src/vue/ai/index.d.ts +5 -3
- package/dist/src/vue/ai/useRAG.d.ts +5 -4
- package/dist/src/vue/ai/useRAGStream.d.ts +1 -1
- package/dist/src/vue/ai/useRAGStreamProgress.d.ts +1 -1
- package/dist/src/vue/ai/useRAGWorkflow.d.ts +1 -1
- package/dist/svelte/ai/index.js +22 -22
- package/dist/svelte/ai/index.js.map +5 -5
- package/dist/vue/ai/index.js +22 -22
- package/dist/vue/ai/index.js.map +6 -6
- package/package.json +7 -7
- package/dist/src/ai/client/createRAGTransport.d.ts +0 -2
- package/dist/src/angular/ai/ai-rag-transport.service.d.ts +0 -1
- package/dist/src/react/ai/useRAGTransport.d.ts +0 -2
- package/dist/src/react/ai/useRAGTransportProgress.d.ts +0 -2
- package/dist/src/svelte/ai/createRAGTransport.d.ts +0 -2
- package/dist/src/svelte/ai/createRAGTransportProgress.d.ts +0 -2
- package/dist/src/vue/ai/useRAGTransport.d.ts +0 -2
- package/dist/src/vue/ai/useRAGTransportProgress.d.ts +0 -2
package/dist/angular/ai/index.js
CHANGED
|
@@ -848,911 +848,929 @@ class AIStreamService {
|
|
|
848
848
|
AIStreamService = __legacyDecorateClassTS([
|
|
849
849
|
Injectable({ providedIn: "root" })
|
|
850
850
|
], AIStreamService);
|
|
851
|
-
// src/angular/ai/rag-
|
|
852
|
-
import { Injectable as
|
|
851
|
+
// src/angular/ai/ai-rag-workflow.service.ts
|
|
852
|
+
import { computed as computed3, Injectable as Injectable3 } from "@angular/core";
|
|
853
853
|
|
|
854
|
-
// src/ai/
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
854
|
+
// src/angular/ai/ai-rag-stream.service.ts
|
|
855
|
+
import { computed as computed2, Injectable as Injectable2 } from "@angular/core";
|
|
856
|
+
|
|
857
|
+
// src/ai/rag/presentation.ts
|
|
858
|
+
var buildSourceGroupKey = (source) => source.source ?? source.title ?? source.chunkId;
|
|
859
|
+
var buildSourceLabel = (source) => source.source ?? source.title ?? source.chunkId;
|
|
860
|
+
var getContextNumber = (value) => typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
|
861
|
+
var getContextString = (value) => typeof value === "string" && value.trim().length > 0 ? value.trim() : undefined;
|
|
862
|
+
var formatTimestampLabel = (value) => {
|
|
863
|
+
const timestamp = typeof value === "number" && Number.isFinite(value) ? value : typeof value === "string" ? Date.parse(value) : Number.NaN;
|
|
864
|
+
if (!Number.isFinite(timestamp)) {
|
|
865
|
+
return;
|
|
866
|
+
}
|
|
867
|
+
return new Date(timestamp).toLocaleString("en-US", {
|
|
868
|
+
dateStyle: "medium",
|
|
869
|
+
timeStyle: "short"
|
|
870
|
+
});
|
|
858
871
|
};
|
|
859
|
-
var
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
872
|
+
var formatMediaTimestamp = (value) => {
|
|
873
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value < 0) {
|
|
874
|
+
return;
|
|
875
|
+
}
|
|
876
|
+
const totalSeconds = Math.floor(value / 1000);
|
|
877
|
+
const minutes = Math.floor(totalSeconds / 60);
|
|
878
|
+
const seconds = totalSeconds % 60;
|
|
879
|
+
const milliseconds = Math.floor(value % 1000);
|
|
880
|
+
return `${String(minutes).padStart(2, "0")}:${String(seconds).padStart(2, "0")}.${String(milliseconds).padStart(3, "0")}`;
|
|
863
881
|
};
|
|
864
|
-
var
|
|
865
|
-
|
|
866
|
-
|
|
882
|
+
var getAttachmentName = (source, title) => {
|
|
883
|
+
const sourceAttachment = source?.split("/").at(-1);
|
|
884
|
+
if (sourceAttachment && sourceAttachment.includes(".")) {
|
|
885
|
+
return sourceAttachment;
|
|
867
886
|
}
|
|
868
|
-
|
|
887
|
+
const titleAttachment = title?.split(" \xB7 ").at(-1);
|
|
888
|
+
if (titleAttachment && titleAttachment.includes(".")) {
|
|
889
|
+
return titleAttachment;
|
|
890
|
+
}
|
|
891
|
+
return;
|
|
869
892
|
};
|
|
870
|
-
var
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
893
|
+
var buildContextLabel = (metadata) => {
|
|
894
|
+
if (!metadata) {
|
|
895
|
+
return;
|
|
896
|
+
}
|
|
897
|
+
const emailKind = getContextString(metadata.emailKind);
|
|
898
|
+
if (emailKind === "attachment") {
|
|
899
|
+
return "Attachment evidence";
|
|
900
|
+
}
|
|
901
|
+
if (emailKind === "message") {
|
|
902
|
+
const from = getContextString(metadata.from);
|
|
903
|
+
return from ? `Message from ${from}` : "Message evidence";
|
|
904
|
+
}
|
|
905
|
+
const page = getContextNumber(metadata.page) ?? getContextNumber(metadata.pageNumber) ?? (typeof metadata.pageIndex === "number" ? metadata.pageIndex + 1 : undefined);
|
|
906
|
+
if (page) {
|
|
907
|
+
return `Page ${page}`;
|
|
908
|
+
}
|
|
909
|
+
const sheet = getContextString(metadata.sheetName) ?? (Array.isArray(metadata.sheetNames) ? getContextString(metadata.sheetNames[0]) : undefined);
|
|
910
|
+
if (sheet) {
|
|
911
|
+
return `Sheet ${sheet}`;
|
|
912
|
+
}
|
|
913
|
+
const slide = getContextNumber(metadata.slide) ?? getContextNumber(metadata.slideNumber) ?? (typeof metadata.slideIndex === "number" ? metadata.slideIndex + 1 : undefined);
|
|
914
|
+
if (slide) {
|
|
915
|
+
return `Slide ${slide}`;
|
|
916
|
+
}
|
|
917
|
+
const archiveEntry = getContextString(metadata.archiveEntryPath) ?? getContextString(metadata.entryPath);
|
|
918
|
+
if (archiveEntry) {
|
|
919
|
+
return `Archive entry ${archiveEntry}`;
|
|
920
|
+
}
|
|
921
|
+
const threadTopic = getContextString(metadata.threadTopic);
|
|
922
|
+
if (threadTopic) {
|
|
923
|
+
return `Thread ${threadTopic}`;
|
|
924
|
+
}
|
|
925
|
+
const speaker = getContextString(metadata.speaker);
|
|
926
|
+
if (speaker) {
|
|
927
|
+
return `Speaker ${speaker}`;
|
|
928
|
+
}
|
|
929
|
+
return;
|
|
930
|
+
};
|
|
931
|
+
var buildLocatorLabel = (metadata, source, title) => {
|
|
932
|
+
if (!metadata) {
|
|
933
|
+
return;
|
|
934
|
+
}
|
|
935
|
+
const page = getContextNumber(metadata.page) ?? getContextNumber(metadata.pageNumber) ?? (typeof metadata.pageIndex === "number" ? metadata.pageIndex + 1 : undefined);
|
|
936
|
+
if (page) {
|
|
937
|
+
return `Page ${page}`;
|
|
938
|
+
}
|
|
939
|
+
const sheet = getContextString(metadata.sheetName) ?? (Array.isArray(metadata.sheetNames) ? getContextString(metadata.sheetNames[0]) : undefined);
|
|
940
|
+
if (sheet) {
|
|
941
|
+
return `Sheet ${sheet}`;
|
|
942
|
+
}
|
|
943
|
+
const slide = getContextNumber(metadata.slide) ?? getContextNumber(metadata.slideNumber) ?? (typeof metadata.slideIndex === "number" ? metadata.slideIndex + 1 : undefined);
|
|
944
|
+
if (slide) {
|
|
945
|
+
return `Slide ${slide}`;
|
|
946
|
+
}
|
|
947
|
+
const archiveEntry = getContextString(metadata.archiveEntryPath) ?? getContextString(metadata.entryPath);
|
|
948
|
+
if (archiveEntry) {
|
|
949
|
+
return `Archive entry ${archiveEntry}`;
|
|
950
|
+
}
|
|
951
|
+
const emailKind = getContextString(metadata.emailKind);
|
|
952
|
+
if (emailKind === "attachment") {
|
|
953
|
+
const attachmentName = getContextString(metadata.attachmentName) ?? getAttachmentName(source, title);
|
|
954
|
+
return attachmentName ? `Attachment ${attachmentName}` : "Attachment";
|
|
955
|
+
}
|
|
956
|
+
const mediaStart = formatMediaTimestamp(metadata.startMs);
|
|
957
|
+
const mediaEnd = formatMediaTimestamp(metadata.endMs);
|
|
958
|
+
if (mediaStart && mediaEnd) {
|
|
959
|
+
return `Timestamp ${mediaStart} - ${mediaEnd}`;
|
|
960
|
+
}
|
|
961
|
+
if (mediaStart) {
|
|
962
|
+
return `Timestamp ${mediaStart}`;
|
|
963
|
+
}
|
|
964
|
+
return;
|
|
965
|
+
};
|
|
966
|
+
var buildProvenanceLabel = (metadata) => {
|
|
967
|
+
if (!metadata) {
|
|
968
|
+
return;
|
|
969
|
+
}
|
|
970
|
+
const threadTopic = getContextString(metadata.threadTopic);
|
|
971
|
+
const from = getContextString(metadata.from);
|
|
972
|
+
const sentAt = formatTimestampLabel(metadata.sentAt) ?? formatTimestampLabel(metadata.receivedAt);
|
|
973
|
+
const speaker = getContextString(metadata.speaker);
|
|
974
|
+
const mediaKind = getContextString(metadata.mediaKind);
|
|
975
|
+
const transcriptSource = getContextString(metadata.transcriptSource);
|
|
976
|
+
const pdfTextMode = getContextString(metadata.pdfTextMode);
|
|
977
|
+
const ocrEngine = getContextString(metadata.ocrEngine);
|
|
978
|
+
const labels = [
|
|
979
|
+
pdfTextMode ? `PDF ${pdfTextMode}` : "",
|
|
980
|
+
ocrEngine ? `OCR ${ocrEngine}` : "",
|
|
981
|
+
mediaKind ? `Media ${mediaKind}` : "",
|
|
982
|
+
transcriptSource ? `Transcript ${transcriptSource}` : "",
|
|
983
|
+
threadTopic ? `Thread ${threadTopic}` : "",
|
|
984
|
+
speaker ? `Speaker ${speaker}` : "",
|
|
985
|
+
from ? `Sender ${from}` : "",
|
|
986
|
+
sentAt ? `Sent ${sentAt}` : ""
|
|
987
|
+
].filter((value) => value.length > 0);
|
|
988
|
+
return labels.length > 0 ? labels.join(" \xB7 ") : undefined;
|
|
989
|
+
};
|
|
990
|
+
var buildRAGCitationReferenceMap = (citations) => Object.fromEntries(citations.map((citation, index) => [citation.chunkId, index + 1]));
|
|
991
|
+
var buildRAGCitations = (sources) => {
|
|
992
|
+
const unique = new Map;
|
|
993
|
+
for (const source of sources) {
|
|
994
|
+
const key = source.chunkId;
|
|
995
|
+
const existing = unique.get(key);
|
|
996
|
+
const hasBetterExisting = existing !== undefined && existing.score >= source.score;
|
|
997
|
+
if (hasBetterExisting)
|
|
998
|
+
continue;
|
|
999
|
+
unique.set(key, {
|
|
1000
|
+
chunkId: source.chunkId,
|
|
1001
|
+
contextLabel: buildContextLabel(source.metadata),
|
|
1002
|
+
key,
|
|
1003
|
+
label: buildSourceLabel(source),
|
|
1004
|
+
locatorLabel: buildLocatorLabel(source.metadata, source.source, source.title),
|
|
1005
|
+
metadata: source.metadata,
|
|
1006
|
+
provenanceLabel: buildProvenanceLabel(source.metadata),
|
|
1007
|
+
score: source.score,
|
|
1008
|
+
source: source.source,
|
|
1009
|
+
text: source.text,
|
|
1010
|
+
title: source.title
|
|
1011
|
+
});
|
|
1012
|
+
}
|
|
1013
|
+
return [...unique.values()].sort((left, right) => {
|
|
1014
|
+
if (right.score !== left.score) {
|
|
1015
|
+
return right.score - left.score;
|
|
875
1016
|
}
|
|
876
|
-
|
|
877
|
-
|
|
1017
|
+
return left.label.localeCompare(right.label);
|
|
1018
|
+
});
|
|
878
1019
|
};
|
|
879
|
-
var
|
|
880
|
-
const
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
1020
|
+
var buildExcerpt = (text, maxLength = 160) => {
|
|
1021
|
+
const normalized = text.replaceAll(/\s+/g, " ").trim();
|
|
1022
|
+
if (normalized.length <= maxLength) {
|
|
1023
|
+
return normalized;
|
|
1024
|
+
}
|
|
1025
|
+
return `${normalized.slice(0, Math.max(0, maxLength - 1)).trimEnd()}\u2026`;
|
|
1026
|
+
};
|
|
1027
|
+
var buildGroundingReferenceEvidenceLabel = (reference) => [reference.label, reference.locatorLabel, reference.contextLabel].filter((value) => Boolean(value && value.length > 0)).filter((value, index, values) => values.findIndex((entry) => entry === value) === index).join(" \xB7 ");
|
|
1028
|
+
var buildGroundingReferenceEvidenceSummary = (reference) => [
|
|
1029
|
+
reference.source ?? reference.title ?? reference.chunkId,
|
|
1030
|
+
reference.provenanceLabel
|
|
1031
|
+
].filter((value) => Boolean(value && value.length > 0)).join(" \xB7 ");
|
|
1032
|
+
var buildGroundedAnswerCitationDetail = (reference) => ({
|
|
1033
|
+
contextLabel: reference.contextLabel,
|
|
1034
|
+
evidenceLabel: buildGroundingReferenceEvidenceLabel(reference),
|
|
1035
|
+
evidenceSummary: buildGroundingReferenceEvidenceSummary(reference),
|
|
1036
|
+
excerpt: reference.excerpt,
|
|
1037
|
+
label: reference.label,
|
|
1038
|
+
locatorLabel: reference.locatorLabel,
|
|
1039
|
+
number: reference.number,
|
|
1040
|
+
provenanceLabel: reference.provenanceLabel,
|
|
1041
|
+
source: reference.source,
|
|
1042
|
+
title: reference.title
|
|
1043
|
+
});
|
|
1044
|
+
var buildRAGGroundedAnswer = (content, sources) => {
|
|
1045
|
+
const references = buildRAGGroundingReferences(sources);
|
|
1046
|
+
const referenceMap = new Map(references.map((reference) => [reference.number, reference]));
|
|
1047
|
+
const parts = [];
|
|
1048
|
+
const ungroundedReferenceNumbers = new Set;
|
|
1049
|
+
const citationPattern = /\[(\d+(?:\s*,\s*\d+)*)\]/g;
|
|
1050
|
+
let cursor = 0;
|
|
1051
|
+
for (const match of content.matchAll(citationPattern)) {
|
|
1052
|
+
const raw = match[0];
|
|
1053
|
+
const numbers = (match[1] ?? "").split(",").map((value) => Number.parseInt(value.trim(), 10)).filter((value) => Number.isInteger(value) && value > 0);
|
|
1054
|
+
const start = match.index ?? cursor;
|
|
1055
|
+
if (start > cursor) {
|
|
1056
|
+
parts.push({
|
|
1057
|
+
text: content.slice(cursor, start),
|
|
1058
|
+
type: "text"
|
|
904
1059
|
});
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
1060
|
+
}
|
|
1061
|
+
const resolvedReferences = numbers.map((number) => referenceMap.get(number)).filter((reference) => Boolean(reference));
|
|
1062
|
+
for (const number of numbers) {
|
|
1063
|
+
if (!referenceMap.has(number)) {
|
|
1064
|
+
ungroundedReferenceNumbers.add(number);
|
|
910
1065
|
}
|
|
911
|
-
return parseJson(response);
|
|
912
|
-
},
|
|
913
|
-
async deleteDocument(id) {
|
|
914
|
-
const response = await fetchImpl(`${basePath}/documents/${encodeURIComponent(id)}`, {
|
|
915
|
-
method: "DELETE"
|
|
916
|
-
});
|
|
917
|
-
if (!response.ok) {
|
|
918
|
-
return {
|
|
919
|
-
error: await toErrorMessage(response),
|
|
920
|
-
ok: false
|
|
921
|
-
};
|
|
922
|
-
}
|
|
923
|
-
return parseJson(response);
|
|
924
|
-
},
|
|
925
|
-
async documentChunks(id) {
|
|
926
|
-
const response = await fetchImpl(`${basePath}/documents/${encodeURIComponent(id)}/chunks`);
|
|
927
|
-
if (!response.ok) {
|
|
928
|
-
const error = await toErrorMessage(response);
|
|
929
|
-
const errorResponse = {
|
|
930
|
-
error,
|
|
931
|
-
ok: false
|
|
932
|
-
};
|
|
933
|
-
return errorResponse;
|
|
934
|
-
}
|
|
935
|
-
return parseJson(response);
|
|
936
|
-
},
|
|
937
|
-
async documents(kind) {
|
|
938
|
-
const query = kind ? `?kind=${encodeURIComponent(kind)}` : "";
|
|
939
|
-
const response = await fetchImpl(`${basePath}/documents${query}`);
|
|
940
|
-
if (!response.ok) {
|
|
941
|
-
throw new Error(await toErrorMessage(response));
|
|
942
|
-
}
|
|
943
|
-
return parseJson(response);
|
|
944
|
-
},
|
|
945
|
-
async evaluate(input) {
|
|
946
|
-
const response = await fetchImpl(`${basePath}/evaluate`, {
|
|
947
|
-
body: JSON.stringify(input),
|
|
948
|
-
headers: jsonHeaders,
|
|
949
|
-
method: "POST"
|
|
950
|
-
});
|
|
951
|
-
if (!response.ok) {
|
|
952
|
-
throw new Error(await toErrorMessage(response));
|
|
953
|
-
}
|
|
954
|
-
return parseJson(response);
|
|
955
|
-
},
|
|
956
|
-
async ingest(chunks) {
|
|
957
|
-
const response = await fetchImpl(`${basePath}/ingest`, {
|
|
958
|
-
body: JSON.stringify({ chunks }),
|
|
959
|
-
headers: jsonHeaders,
|
|
960
|
-
method: "POST"
|
|
961
|
-
});
|
|
962
|
-
if (!response.ok) {
|
|
963
|
-
return {
|
|
964
|
-
error: await toErrorMessage(response),
|
|
965
|
-
ok: false
|
|
966
|
-
};
|
|
967
|
-
}
|
|
968
|
-
return parseJson(response);
|
|
969
|
-
},
|
|
970
|
-
async ingestDocuments(input) {
|
|
971
|
-
const response = await fetchImpl(`${basePath}/ingest`, {
|
|
972
|
-
body: JSON.stringify(input),
|
|
973
|
-
headers: jsonHeaders,
|
|
974
|
-
method: "POST"
|
|
975
|
-
});
|
|
976
|
-
if (!response.ok) {
|
|
977
|
-
return {
|
|
978
|
-
error: await toErrorMessage(response),
|
|
979
|
-
ok: false
|
|
980
|
-
};
|
|
981
|
-
}
|
|
982
|
-
return parseJson(response);
|
|
983
|
-
},
|
|
984
|
-
async ingestUploads(input) {
|
|
985
|
-
const response = await fetchImpl(`${basePath}/ingest`, {
|
|
986
|
-
body: JSON.stringify(input),
|
|
987
|
-
headers: jsonHeaders,
|
|
988
|
-
method: "POST"
|
|
989
|
-
});
|
|
990
|
-
if (!response.ok) {
|
|
991
|
-
return {
|
|
992
|
-
error: await toErrorMessage(response),
|
|
993
|
-
ok: false
|
|
994
|
-
};
|
|
995
|
-
}
|
|
996
|
-
return parseJson(response);
|
|
997
|
-
},
|
|
998
|
-
async ingestUrls(input) {
|
|
999
|
-
const response = await fetchImpl(`${basePath}/ingest`, {
|
|
1000
|
-
body: JSON.stringify(input),
|
|
1001
|
-
headers: jsonHeaders,
|
|
1002
|
-
method: "POST"
|
|
1003
|
-
});
|
|
1004
|
-
if (!response.ok) {
|
|
1005
|
-
return {
|
|
1006
|
-
error: await toErrorMessage(response),
|
|
1007
|
-
ok: false
|
|
1008
|
-
};
|
|
1009
|
-
}
|
|
1010
|
-
return parseJson(response);
|
|
1011
|
-
},
|
|
1012
|
-
async ops() {
|
|
1013
|
-
const response = await fetchImpl(`${basePath}/ops`);
|
|
1014
|
-
if (!response.ok) {
|
|
1015
|
-
throw new Error(await toErrorMessage(response));
|
|
1016
|
-
}
|
|
1017
|
-
return parseJson(response);
|
|
1018
|
-
},
|
|
1019
|
-
async syncSources() {
|
|
1020
|
-
const response = await fetchImpl(`${basePath}/sync`);
|
|
1021
|
-
if (!response.ok) {
|
|
1022
|
-
throw new Error(await toErrorMessage(response));
|
|
1023
|
-
}
|
|
1024
|
-
return parseJson(response);
|
|
1025
|
-
},
|
|
1026
|
-
async syncAllSources(options2) {
|
|
1027
|
-
const response = await fetchImpl(`${basePath}/sync`, {
|
|
1028
|
-
body: options2?.background === true ? JSON.stringify({ background: true }) : undefined,
|
|
1029
|
-
headers: options2?.background === true ? jsonHeaders : undefined,
|
|
1030
|
-
method: "POST"
|
|
1031
|
-
});
|
|
1032
|
-
if (!response.ok) {
|
|
1033
|
-
return {
|
|
1034
|
-
error: await toErrorMessage(response),
|
|
1035
|
-
ok: false
|
|
1036
|
-
};
|
|
1037
|
-
}
|
|
1038
|
-
return parseJson(response);
|
|
1039
|
-
},
|
|
1040
|
-
async syncSource(id, options2) {
|
|
1041
|
-
const response = await fetchImpl(`${basePath}/sync/${encodeURIComponent(id)}`, {
|
|
1042
|
-
body: options2?.background === true ? JSON.stringify({ background: true }) : undefined,
|
|
1043
|
-
headers: options2?.background === true ? jsonHeaders : undefined,
|
|
1044
|
-
method: "POST"
|
|
1045
|
-
});
|
|
1046
|
-
if (!response.ok) {
|
|
1047
|
-
return {
|
|
1048
|
-
error: await toErrorMessage(response),
|
|
1049
|
-
ok: false
|
|
1050
|
-
};
|
|
1051
|
-
}
|
|
1052
|
-
return parseJson(response);
|
|
1053
|
-
},
|
|
1054
|
-
async reindexDocument(id) {
|
|
1055
|
-
const response = await fetchImpl(`${basePath}/reindex/documents/${encodeURIComponent(id)}`, {
|
|
1056
|
-
method: "POST"
|
|
1057
|
-
});
|
|
1058
|
-
if (!response.ok) {
|
|
1059
|
-
return {
|
|
1060
|
-
error: await toErrorMessage(response),
|
|
1061
|
-
ok: false
|
|
1062
|
-
};
|
|
1063
|
-
}
|
|
1064
|
-
return parseJson(response);
|
|
1065
|
-
},
|
|
1066
|
-
async reindexSource(source) {
|
|
1067
|
-
const response = await fetchImpl(`${basePath}/reindex/source`, {
|
|
1068
|
-
body: JSON.stringify({ source }),
|
|
1069
|
-
headers: jsonHeaders,
|
|
1070
|
-
method: "POST"
|
|
1071
|
-
});
|
|
1072
|
-
if (!response.ok) {
|
|
1073
|
-
return {
|
|
1074
|
-
error: await toErrorMessage(response),
|
|
1075
|
-
ok: false
|
|
1076
|
-
};
|
|
1077
|
-
}
|
|
1078
|
-
return parseJson(response);
|
|
1079
|
-
},
|
|
1080
|
-
async reseed() {
|
|
1081
|
-
const response = await fetchImpl(`${basePath}/reseed`, {
|
|
1082
|
-
method: "POST"
|
|
1083
|
-
});
|
|
1084
|
-
if (!response.ok) {
|
|
1085
|
-
return {
|
|
1086
|
-
error: await toErrorMessage(response),
|
|
1087
|
-
ok: false
|
|
1088
|
-
};
|
|
1089
|
-
}
|
|
1090
|
-
return parseJson(response);
|
|
1091
|
-
},
|
|
1092
|
-
async reset() {
|
|
1093
|
-
const response = await fetchImpl(`${basePath}/reset`, {
|
|
1094
|
-
method: "POST"
|
|
1095
|
-
});
|
|
1096
|
-
if (!response.ok) {
|
|
1097
|
-
return {
|
|
1098
|
-
error: await toErrorMessage(response),
|
|
1099
|
-
ok: false
|
|
1100
|
-
};
|
|
1101
|
-
}
|
|
1102
|
-
return parseJson(response);
|
|
1103
|
-
},
|
|
1104
|
-
async search(input) {
|
|
1105
|
-
const response = await fetchImpl(`${basePath}/search`, {
|
|
1106
|
-
body: JSON.stringify(input),
|
|
1107
|
-
headers: jsonHeaders,
|
|
1108
|
-
method: "POST"
|
|
1109
|
-
});
|
|
1110
|
-
if (!response.ok) {
|
|
1111
|
-
throw new Error(await toErrorMessage(response));
|
|
1112
|
-
}
|
|
1113
|
-
const payload = await parseJson(response);
|
|
1114
|
-
if (!payload.ok) {
|
|
1115
|
-
throw new Error(payload.error ?? "RAG search failed");
|
|
1116
|
-
}
|
|
1117
|
-
return payload.results ?? [];
|
|
1118
|
-
},
|
|
1119
|
-
async status() {
|
|
1120
|
-
const response = await fetchImpl(`${basePath}/status`);
|
|
1121
|
-
if (!response.ok) {
|
|
1122
|
-
throw new Error(await toErrorMessage(response));
|
|
1123
|
-
}
|
|
1124
|
-
return parseJson(response);
|
|
1125
|
-
}
|
|
1126
|
-
};
|
|
1127
|
-
};
|
|
1128
|
-
|
|
1129
|
-
// src/angular/ai/rag-client.service.ts
|
|
1130
|
-
class RAGClientService {
|
|
1131
|
-
clients = new Map;
|
|
1132
|
-
client(path) {
|
|
1133
|
-
const existing = this.clients.get(path);
|
|
1134
|
-
if (existing) {
|
|
1135
|
-
return existing;
|
|
1136
1066
|
}
|
|
1137
|
-
const
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
ingestUrls(path, input) {
|
|
1148
|
-
return this.client(path).ingestUrls(input);
|
|
1149
|
-
}
|
|
1150
|
-
ingestUploads(path, input) {
|
|
1151
|
-
return this.client(path).ingestUploads(input);
|
|
1067
|
+
const unresolvedNumbers = numbers.filter((number) => !referenceMap.has(number));
|
|
1068
|
+
parts.push({
|
|
1069
|
+
referenceNumbers: numbers,
|
|
1070
|
+
referenceDetails: resolvedReferences.map(buildGroundedAnswerCitationDetail),
|
|
1071
|
+
references: resolvedReferences,
|
|
1072
|
+
text: raw,
|
|
1073
|
+
type: "citation",
|
|
1074
|
+
unresolvedReferenceNumbers: unresolvedNumbers
|
|
1075
|
+
});
|
|
1076
|
+
cursor = start + raw.length;
|
|
1152
1077
|
}
|
|
1153
|
-
|
|
1154
|
-
|
|
1078
|
+
if (cursor < content.length || parts.length === 0) {
|
|
1079
|
+
parts.push({
|
|
1080
|
+
text: content.slice(cursor),
|
|
1081
|
+
type: "text"
|
|
1082
|
+
});
|
|
1155
1083
|
}
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1084
|
+
const hasCitations = parts.some((part) => part.type === "citation");
|
|
1085
|
+
const coverage = !hasCitations ? "ungrounded" : ungroundedReferenceNumbers.size === 0 ? "grounded" : references.length > 0 ? "partial" : "ungrounded";
|
|
1086
|
+
return {
|
|
1087
|
+
content,
|
|
1088
|
+
coverage,
|
|
1089
|
+
hasCitations,
|
|
1090
|
+
parts,
|
|
1091
|
+
references,
|
|
1092
|
+
ungroundedReferenceNumbers: [...ungroundedReferenceNumbers].sort((left, right) => left - right)
|
|
1093
|
+
};
|
|
1094
|
+
};
|
|
1095
|
+
var buildRAGGroundingReferences = (sources) => {
|
|
1096
|
+
const citations = buildRAGCitations(sources);
|
|
1097
|
+
const citationReferenceMap = buildRAGCitationReferenceMap(citations);
|
|
1098
|
+
return citations.map((citation) => ({
|
|
1099
|
+
chunkId: citation.chunkId,
|
|
1100
|
+
contextLabel: buildContextLabel(citation.metadata),
|
|
1101
|
+
excerpt: buildExcerpt(citation.text),
|
|
1102
|
+
label: citation.label,
|
|
1103
|
+
locatorLabel: citation.locatorLabel ?? buildLocatorLabel(citation.metadata, citation.source, citation.title),
|
|
1104
|
+
metadata: citation.metadata,
|
|
1105
|
+
number: citationReferenceMap[citation.chunkId] ?? 0,
|
|
1106
|
+
provenanceLabel: citation.provenanceLabel ?? buildProvenanceLabel(citation.metadata),
|
|
1107
|
+
score: citation.score,
|
|
1108
|
+
source: citation.source,
|
|
1109
|
+
text: citation.text,
|
|
1110
|
+
title: citation.title
|
|
1111
|
+
}));
|
|
1112
|
+
};
|
|
1113
|
+
var buildRAGRetrievedState = (messages) => {
|
|
1114
|
+
const message = getLatestRetrievedMessage(messages);
|
|
1115
|
+
if (!message) {
|
|
1116
|
+
return null;
|
|
1161
1117
|
}
|
|
1162
|
-
|
|
1163
|
-
|
|
1118
|
+
const sources = message.sources ?? [];
|
|
1119
|
+
const groundedAnswer = buildRAGGroundedAnswer(message.content, sources);
|
|
1120
|
+
return {
|
|
1121
|
+
citationReferenceMap: buildRAGCitationReferenceMap(buildRAGCitations(sources)),
|
|
1122
|
+
citations: buildRAGCitations(sources),
|
|
1123
|
+
conversationId: message.conversationId,
|
|
1124
|
+
groundedAnswer,
|
|
1125
|
+
messageId: message.id,
|
|
1126
|
+
retrievalDurationMs: message.retrievalDurationMs,
|
|
1127
|
+
retrievalStartedAt: message.retrievalStartedAt,
|
|
1128
|
+
retrievedAt: message.retrievedAt,
|
|
1129
|
+
sourceGroups: buildRAGSourceGroups(sources),
|
|
1130
|
+
sourceSummaries: buildRAGSourceSummaries(sources),
|
|
1131
|
+
sources
|
|
1132
|
+
};
|
|
1133
|
+
};
|
|
1134
|
+
var buildRAGSourceSummaries = (sources) => {
|
|
1135
|
+
const sourceGroups = buildRAGSourceGroups(sources);
|
|
1136
|
+
const citations = buildRAGCitations(sources);
|
|
1137
|
+
const citationReferenceMap = buildRAGCitationReferenceMap(citations);
|
|
1138
|
+
return sourceGroups.map((group) => {
|
|
1139
|
+
const groupCitations = citations.filter((citation) => group.chunks.some((chunk) => chunk.chunkId === citation.chunkId));
|
|
1140
|
+
const leadChunk = group.chunks.slice().sort((left, right) => right.score - left.score)[0];
|
|
1141
|
+
return {
|
|
1142
|
+
bestScore: group.bestScore,
|
|
1143
|
+
citationNumbers: groupCitations.map((citation) => citationReferenceMap[citation.chunkId] ?? 0),
|
|
1144
|
+
citations: groupCitations,
|
|
1145
|
+
chunkIds: group.chunks.map((chunk) => chunk.chunkId),
|
|
1146
|
+
contextLabel: buildContextLabel(leadChunk?.metadata),
|
|
1147
|
+
count: group.count,
|
|
1148
|
+
excerpt: buildExcerpt(leadChunk?.text ?? ""),
|
|
1149
|
+
key: group.key,
|
|
1150
|
+
label: group.label,
|
|
1151
|
+
locatorLabel: buildLocatorLabel(leadChunk?.metadata, leadChunk?.source, leadChunk?.title),
|
|
1152
|
+
provenanceLabel: buildProvenanceLabel(leadChunk?.metadata),
|
|
1153
|
+
source: group.source,
|
|
1154
|
+
title: group.title
|
|
1155
|
+
};
|
|
1156
|
+
});
|
|
1157
|
+
};
|
|
1158
|
+
var buildStreamProgressState = (messages) => {
|
|
1159
|
+
const latestMessage = getLatestAssistantMessage(messages);
|
|
1160
|
+
const retrieved = latestMessage ? buildRAGRetrievedState(messages) : undefined;
|
|
1161
|
+
return {
|
|
1162
|
+
conversationId: latestMessage?.conversationId,
|
|
1163
|
+
latestMessage,
|
|
1164
|
+
messageId: latestMessage?.id,
|
|
1165
|
+
retrieved,
|
|
1166
|
+
sourceCount: retrieved?.sources.length ?? latestMessage?.sources?.length ?? 0
|
|
1167
|
+
};
|
|
1168
|
+
};
|
|
1169
|
+
var buildRAGStreamProgress = ({
|
|
1170
|
+
error,
|
|
1171
|
+
isStreaming,
|
|
1172
|
+
messages
|
|
1173
|
+
}) => {
|
|
1174
|
+
const stage = resolveRAGStreamStage({
|
|
1175
|
+
error,
|
|
1176
|
+
isStreaming,
|
|
1177
|
+
messages
|
|
1178
|
+
});
|
|
1179
|
+
const state = buildStreamProgressState(messages);
|
|
1180
|
+
const hasSources = state.sourceCount > 0;
|
|
1181
|
+
const hasRetrieved = stage === "retrieved" || state.retrieved !== undefined || state.latestMessage?.retrievedAt !== undefined;
|
|
1182
|
+
const hasThinking = typeof state.latestMessage?.thinking === "string" && state.latestMessage.thinking.length > 0;
|
|
1183
|
+
const hasToolCalls = (state.latestMessage?.toolCalls?.length ?? 0) > 0;
|
|
1184
|
+
return {
|
|
1185
|
+
conversationId: state.conversationId,
|
|
1186
|
+
hasContent: typeof state.latestMessage?.content === "string" && state.latestMessage.content.length > 0,
|
|
1187
|
+
hasRetrieved,
|
|
1188
|
+
hasSources,
|
|
1189
|
+
hasThinking,
|
|
1190
|
+
hasToolCalls,
|
|
1191
|
+
isComplete: stage === "complete",
|
|
1192
|
+
isError: stage === "error",
|
|
1193
|
+
isIdle: stage === "idle",
|
|
1194
|
+
isRetrieved: stage === "retrieved",
|
|
1195
|
+
isRetrieving: stage === "submitting" || stage === "retrieving",
|
|
1196
|
+
isStreaming: stage === "streaming",
|
|
1197
|
+
isSubmitting: stage === "submitting",
|
|
1198
|
+
latestMessage: state.latestMessage,
|
|
1199
|
+
messageId: state.messageId,
|
|
1200
|
+
retrievalDurationMs: state.retrieved?.retrievalDurationMs,
|
|
1201
|
+
retrievalStartedAt: state.retrieved?.retrievalStartedAt,
|
|
1202
|
+
retrievedAt: state.retrieved?.retrievedAt,
|
|
1203
|
+
sourceCount: state.sourceCount,
|
|
1204
|
+
stage
|
|
1205
|
+
};
|
|
1206
|
+
};
|
|
1207
|
+
var buildRAGAnswerWorkflowState = ({
|
|
1208
|
+
error,
|
|
1209
|
+
isStreaming,
|
|
1210
|
+
messages
|
|
1211
|
+
}) => {
|
|
1212
|
+
const latestAssistantMessage = getLatestAssistantMessage(messages);
|
|
1213
|
+
const sources = getLatestRAGSources(messages);
|
|
1214
|
+
const sourceGroups = buildRAGSourceGroups(sources);
|
|
1215
|
+
const citations = buildRAGCitations(sources);
|
|
1216
|
+
const citationReferenceMap = buildRAGCitationReferenceMap(citations);
|
|
1217
|
+
const sourceSummaries = buildRAGSourceSummaries(sources);
|
|
1218
|
+
const groundingReferences = buildRAGGroundingReferences(sources);
|
|
1219
|
+
const groundedAnswer = buildRAGGroundedAnswer(latestAssistantMessage?.content ?? "", sources);
|
|
1220
|
+
const retrieval = buildRAGRetrievedState(messages);
|
|
1221
|
+
const progress = buildRAGStreamProgress({
|
|
1222
|
+
error,
|
|
1223
|
+
isStreaming,
|
|
1224
|
+
messages
|
|
1225
|
+
});
|
|
1226
|
+
return {
|
|
1227
|
+
citationReferenceMap,
|
|
1228
|
+
citations,
|
|
1229
|
+
coverage: groundedAnswer.coverage,
|
|
1230
|
+
error,
|
|
1231
|
+
groundedAnswer,
|
|
1232
|
+
groundingReferences,
|
|
1233
|
+
hasCitations: groundedAnswer.hasCitations,
|
|
1234
|
+
hasGrounding: groundingReferences.length > 0,
|
|
1235
|
+
hasRetrieved: progress.hasRetrieved,
|
|
1236
|
+
hasSources: sources.length > 0,
|
|
1237
|
+
isAnswerStreaming: progress.isStreaming,
|
|
1238
|
+
isComplete: progress.isComplete,
|
|
1239
|
+
isError: progress.isError,
|
|
1240
|
+
isIdle: progress.isIdle,
|
|
1241
|
+
isRetrieved: progress.isRetrieved,
|
|
1242
|
+
isRetrieving: progress.isRetrieving,
|
|
1243
|
+
isRunning: progress.isSubmitting || progress.isRetrieving || progress.isStreaming,
|
|
1244
|
+
isSubmitting: progress.isSubmitting,
|
|
1245
|
+
latestAssistantMessage,
|
|
1246
|
+
messages,
|
|
1247
|
+
retrieval,
|
|
1248
|
+
retrievalDurationMs: retrieval?.retrievalDurationMs,
|
|
1249
|
+
retrievalStartedAt: retrieval?.retrievalStartedAt,
|
|
1250
|
+
retrievedAt: retrieval?.retrievedAt,
|
|
1251
|
+
sourceGroups,
|
|
1252
|
+
sourceSummaries,
|
|
1253
|
+
sources,
|
|
1254
|
+
stage: progress.stage,
|
|
1255
|
+
ungroundedReferenceNumbers: groundedAnswer.ungroundedReferenceNumbers
|
|
1256
|
+
};
|
|
1257
|
+
};
|
|
1258
|
+
var buildRAGSourceGroups = (sources) => {
|
|
1259
|
+
const groups = new Map;
|
|
1260
|
+
for (const source of sources) {
|
|
1261
|
+
updateSourceGroup(groups, source);
|
|
1164
1262
|
}
|
|
1165
|
-
|
|
1166
|
-
|
|
1263
|
+
return [...groups.values()].sort((left, right) => {
|
|
1264
|
+
if (right.bestScore !== left.bestScore) {
|
|
1265
|
+
return right.bestScore - left.bestScore;
|
|
1266
|
+
}
|
|
1267
|
+
return left.label.localeCompare(right.label);
|
|
1268
|
+
});
|
|
1269
|
+
};
|
|
1270
|
+
var buildSourceGroup = (source, key) => ({
|
|
1271
|
+
bestScore: source.score,
|
|
1272
|
+
chunks: [source],
|
|
1273
|
+
count: 1,
|
|
1274
|
+
key,
|
|
1275
|
+
label: buildSourceLabel(source),
|
|
1276
|
+
source: source.source,
|
|
1277
|
+
title: source.title
|
|
1278
|
+
});
|
|
1279
|
+
var updateSourceGroup = (groups, source) => {
|
|
1280
|
+
const key = buildSourceGroupKey(source);
|
|
1281
|
+
const existing = groups.get(key);
|
|
1282
|
+
if (!existing) {
|
|
1283
|
+
groups.set(key, buildSourceGroup(source, key));
|
|
1284
|
+
return;
|
|
1167
1285
|
}
|
|
1168
|
-
|
|
1169
|
-
|
|
1286
|
+
existing.bestScore = Math.max(existing.bestScore, source.score);
|
|
1287
|
+
existing.count += 1;
|
|
1288
|
+
existing.chunks.push(source);
|
|
1289
|
+
};
|
|
1290
|
+
var getLatestAssistantMessage = (messages) => {
|
|
1291
|
+
for (let index = messages.length - 1;index >= 0; index -= 1) {
|
|
1292
|
+
const message = messages[index];
|
|
1293
|
+
if (message?.role === "assistant") {
|
|
1294
|
+
return message;
|
|
1295
|
+
}
|
|
1170
1296
|
}
|
|
1171
|
-
|
|
1172
|
-
|
|
1297
|
+
return;
|
|
1298
|
+
};
|
|
1299
|
+
var getLatestRAGSources = (messages) => getLatestAssistantMessage(messages)?.sources ?? [];
|
|
1300
|
+
var getLatestRetrievedMessage = (messages) => {
|
|
1301
|
+
for (let index = messages.length - 1;index >= 0; index -= 1) {
|
|
1302
|
+
const message = messages[index];
|
|
1303
|
+
if (message?.role === "assistant" && (typeof message.retrievedAt === "number" || (message.sources?.length ?? 0) > 0)) {
|
|
1304
|
+
return message;
|
|
1305
|
+
}
|
|
1173
1306
|
}
|
|
1174
|
-
|
|
1175
|
-
|
|
1307
|
+
return;
|
|
1308
|
+
};
|
|
1309
|
+
var resolveRAGStreamStage = ({
|
|
1310
|
+
error,
|
|
1311
|
+
isStreaming,
|
|
1312
|
+
messages
|
|
1313
|
+
}) => {
|
|
1314
|
+
if (error) {
|
|
1315
|
+
return "error";
|
|
1176
1316
|
}
|
|
1177
|
-
|
|
1178
|
-
|
|
1317
|
+
const assistantMessage = getLatestAssistantMessage(messages);
|
|
1318
|
+
if (!assistantMessage) {
|
|
1319
|
+
return isStreaming ? "submitting" : "idle";
|
|
1179
1320
|
}
|
|
1180
|
-
|
|
1181
|
-
|
|
1321
|
+
const isRetrieving = typeof assistantMessage.retrievalStartedAt === "number" && typeof assistantMessage.retrievedAt !== "number";
|
|
1322
|
+
if (isRetrieving) {
|
|
1323
|
+
return "retrieving";
|
|
1182
1324
|
}
|
|
1183
|
-
|
|
1184
|
-
return
|
|
1325
|
+
if (!isStreaming) {
|
|
1326
|
+
return "complete";
|
|
1185
1327
|
}
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
return this.client(path).reset();
|
|
1191
|
-
}
|
|
1192
|
-
reindexDocument(path, id) {
|
|
1193
|
-
return this.client(path).reindexDocument(id);
|
|
1194
|
-
}
|
|
1195
|
-
reindexSource(path, source) {
|
|
1196
|
-
return this.client(path).reindexSource(source);
|
|
1197
|
-
}
|
|
1198
|
-
backends(path) {
|
|
1199
|
-
return this.client(path).backends();
|
|
1328
|
+
const hasRetrieved = typeof assistantMessage.retrievedAt === "number";
|
|
1329
|
+
const hasContent = assistantMessage.content.trim().length > 0 || assistantMessage.thinking?.trim().length || (assistantMessage.toolCalls?.length ?? 0) > 0 || (assistantMessage.images?.length ?? 0) > 0;
|
|
1330
|
+
if (hasRetrieved && !hasContent) {
|
|
1331
|
+
return "retrieved";
|
|
1200
1332
|
}
|
|
1201
|
-
|
|
1202
|
-
|
|
1333
|
+
return "streaming";
|
|
1334
|
+
};
|
|
1335
|
+
|
|
1336
|
+
// src/angular/ai/ai-rag-stream.service.ts
|
|
1337
|
+
class RAGStreamService extends AIStreamService {
|
|
1338
|
+
connect(path, conversationId) {
|
|
1339
|
+
const stream = super.connect(path, conversationId);
|
|
1340
|
+
const workflow = computed2(() => buildRAGAnswerWorkflowState({
|
|
1341
|
+
error: stream.error(),
|
|
1342
|
+
isStreaming: stream.isStreaming(),
|
|
1343
|
+
messages: stream.messages()
|
|
1344
|
+
}));
|
|
1345
|
+
const progress = computed2(() => buildRAGStreamProgress({
|
|
1346
|
+
error: stream.error(),
|
|
1347
|
+
isStreaming: stream.isStreaming(),
|
|
1348
|
+
messages: stream.messages()
|
|
1349
|
+
}));
|
|
1350
|
+
const latestAssistantMessage = computed2(() => workflow().latestAssistantMessage);
|
|
1351
|
+
const sources = computed2(() => workflow().sources);
|
|
1352
|
+
const sourceGroups = computed2(() => workflow().sourceGroups);
|
|
1353
|
+
const citations = computed2(() => workflow().citations);
|
|
1354
|
+
const sourceSummaries = computed2(() => workflow().sourceSummaries);
|
|
1355
|
+
const citationReferenceMap = computed2(() => workflow().citationReferenceMap);
|
|
1356
|
+
const retrieval = computed2(() => workflow().retrieval);
|
|
1357
|
+
const groundedAnswer = computed2(() => workflow().groundedAnswer);
|
|
1358
|
+
const groundingReferences = computed2(() => workflow().groundingReferences);
|
|
1359
|
+
const hasRetrieved = computed2(() => workflow().hasRetrieved);
|
|
1360
|
+
const hasSources = computed2(() => workflow().hasSources);
|
|
1361
|
+
const isRetrieving = computed2(() => workflow().isRetrieving);
|
|
1362
|
+
const isRetrieved = computed2(() => workflow().isRetrieved);
|
|
1363
|
+
const isAnswerStreaming = computed2(() => workflow().isAnswerStreaming);
|
|
1364
|
+
const isComplete = computed2(() => workflow().isComplete);
|
|
1365
|
+
const isError = computed2(() => workflow().isError);
|
|
1366
|
+
const isRunning = computed2(() => workflow().isRunning);
|
|
1367
|
+
const stage = computed2(() => workflow().stage);
|
|
1368
|
+
return {
|
|
1369
|
+
...stream,
|
|
1370
|
+
citations,
|
|
1371
|
+
citationReferenceMap,
|
|
1372
|
+
groundedAnswer,
|
|
1373
|
+
groundingReferences,
|
|
1374
|
+
hasRetrieved,
|
|
1375
|
+
hasSources,
|
|
1376
|
+
isAnswerStreaming,
|
|
1377
|
+
isComplete,
|
|
1378
|
+
isError,
|
|
1379
|
+
isRetrieved,
|
|
1380
|
+
isRetrieving,
|
|
1381
|
+
isRunning,
|
|
1382
|
+
latestAssistantMessage,
|
|
1383
|
+
progress,
|
|
1384
|
+
query: stream.send,
|
|
1385
|
+
retrieval,
|
|
1386
|
+
sourceGroups,
|
|
1387
|
+
sourceSummaries,
|
|
1388
|
+
sources,
|
|
1389
|
+
stage,
|
|
1390
|
+
workflow
|
|
1391
|
+
};
|
|
1203
1392
|
}
|
|
1204
1393
|
}
|
|
1205
|
-
|
|
1394
|
+
RAGStreamService = __legacyDecorateClassTS([
|
|
1206
1395
|
Injectable2({ providedIn: "root" })
|
|
1207
|
-
],
|
|
1208
|
-
// src/angular/ai/ai-rag-stream.service.ts
|
|
1209
|
-
import { computed as computed2, Injectable as Injectable3 } from "@angular/core";
|
|
1396
|
+
], RAGStreamService);
|
|
1210
1397
|
|
|
1211
|
-
// src/ai/rag
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
return;
|
|
1220
|
-
}
|
|
1221
|
-
return new Date(timestamp).toLocaleString("en-US", {
|
|
1222
|
-
dateStyle: "medium",
|
|
1223
|
-
timeStyle: "short"
|
|
1224
|
-
});
|
|
1225
|
-
};
|
|
1226
|
-
var formatMediaTimestamp = (value) => {
|
|
1227
|
-
if (typeof value !== "number" || !Number.isFinite(value) || value < 0) {
|
|
1228
|
-
return;
|
|
1229
|
-
}
|
|
1230
|
-
const totalSeconds = Math.floor(value / 1000);
|
|
1231
|
-
const minutes = Math.floor(totalSeconds / 60);
|
|
1232
|
-
const seconds = totalSeconds % 60;
|
|
1233
|
-
const milliseconds = Math.floor(value % 1000);
|
|
1234
|
-
return `${String(minutes).padStart(2, "0")}:${String(seconds).padStart(2, "0")}.${String(milliseconds).padStart(3, "0")}`;
|
|
1235
|
-
};
|
|
1236
|
-
var getAttachmentName = (source, title) => {
|
|
1237
|
-
const sourceAttachment = source?.split("/").at(-1);
|
|
1238
|
-
if (sourceAttachment && sourceAttachment.includes(".")) {
|
|
1239
|
-
return sourceAttachment;
|
|
1240
|
-
}
|
|
1241
|
-
const titleAttachment = title?.split(" \xB7 ").at(-1);
|
|
1242
|
-
if (titleAttachment && titleAttachment.includes(".")) {
|
|
1243
|
-
return titleAttachment;
|
|
1398
|
+
// src/angular/ai/ai-rag-workflow.service.ts
|
|
1399
|
+
class RAGWorkflowService extends RAGStreamService {
|
|
1400
|
+
connect(path, conversationId) {
|
|
1401
|
+
const stream = super.connect(path, conversationId);
|
|
1402
|
+
return {
|
|
1403
|
+
...stream,
|
|
1404
|
+
state: computed3(() => stream.workflow())
|
|
1405
|
+
};
|
|
1244
1406
|
}
|
|
1245
|
-
|
|
1407
|
+
}
|
|
1408
|
+
RAGWorkflowService = __legacyDecorateClassTS([
|
|
1409
|
+
Injectable3({ providedIn: "root" })
|
|
1410
|
+
], RAGWorkflowService);
|
|
1411
|
+
// src/angular/ai/rag-client.service.ts
|
|
1412
|
+
import { Injectable as Injectable4 } from "@angular/core";
|
|
1413
|
+
|
|
1414
|
+
// src/ai/client/ragClient.ts
|
|
1415
|
+
init_constants();
|
|
1416
|
+
var jsonHeaders = {
|
|
1417
|
+
"Content-Type": "application/json"
|
|
1246
1418
|
};
|
|
1247
|
-
var
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
const emailKind = getContextString(metadata.emailKind);
|
|
1252
|
-
if (emailKind === "attachment") {
|
|
1253
|
-
return "Attachment evidence";
|
|
1254
|
-
}
|
|
1255
|
-
if (emailKind === "message") {
|
|
1256
|
-
const from = getContextString(metadata.from);
|
|
1257
|
-
return from ? `Message from ${from}` : "Message evidence";
|
|
1258
|
-
}
|
|
1259
|
-
const page = getContextNumber(metadata.page) ?? getContextNumber(metadata.pageNumber) ?? (typeof metadata.pageIndex === "number" ? metadata.pageIndex + 1 : undefined);
|
|
1260
|
-
if (page) {
|
|
1261
|
-
return `Page ${page}`;
|
|
1262
|
-
}
|
|
1263
|
-
const sheet = getContextString(metadata.sheetName) ?? (Array.isArray(metadata.sheetNames) ? getContextString(metadata.sheetNames[0]) : undefined);
|
|
1264
|
-
if (sheet) {
|
|
1265
|
-
return `Sheet ${sheet}`;
|
|
1266
|
-
}
|
|
1267
|
-
const slide = getContextNumber(metadata.slide) ?? getContextNumber(metadata.slideNumber) ?? (typeof metadata.slideIndex === "number" ? metadata.slideIndex + 1 : undefined);
|
|
1268
|
-
if (slide) {
|
|
1269
|
-
return `Slide ${slide}`;
|
|
1270
|
-
}
|
|
1271
|
-
const archiveEntry = getContextString(metadata.archiveEntryPath) ?? getContextString(metadata.entryPath);
|
|
1272
|
-
if (archiveEntry) {
|
|
1273
|
-
return `Archive entry ${archiveEntry}`;
|
|
1274
|
-
}
|
|
1275
|
-
const threadTopic = getContextString(metadata.threadTopic);
|
|
1276
|
-
if (threadTopic) {
|
|
1277
|
-
return `Thread ${threadTopic}`;
|
|
1278
|
-
}
|
|
1279
|
-
const speaker = getContextString(metadata.speaker);
|
|
1280
|
-
if (speaker) {
|
|
1281
|
-
return `Speaker ${speaker}`;
|
|
1282
|
-
}
|
|
1283
|
-
return;
|
|
1419
|
+
var normalizeBasePath = (path) => path.endsWith("/") ? path.slice(0, UNFOUND_INDEX) : path;
|
|
1420
|
+
var parseJson = async (response) => {
|
|
1421
|
+
const payload = JSON.parse(await response.text());
|
|
1422
|
+
return payload;
|
|
1284
1423
|
};
|
|
1285
|
-
var
|
|
1286
|
-
if (!
|
|
1287
|
-
return;
|
|
1288
|
-
}
|
|
1289
|
-
const page = getContextNumber(metadata.page) ?? getContextNumber(metadata.pageNumber) ?? (typeof metadata.pageIndex === "number" ? metadata.pageIndex + 1 : undefined);
|
|
1290
|
-
if (page) {
|
|
1291
|
-
return `Page ${page}`;
|
|
1292
|
-
}
|
|
1293
|
-
const sheet = getContextString(metadata.sheetName) ?? (Array.isArray(metadata.sheetNames) ? getContextString(metadata.sheetNames[0]) : undefined);
|
|
1294
|
-
if (sheet) {
|
|
1295
|
-
return `Sheet ${sheet}`;
|
|
1296
|
-
}
|
|
1297
|
-
const slide = getContextNumber(metadata.slide) ?? getContextNumber(metadata.slideNumber) ?? (typeof metadata.slideIndex === "number" ? metadata.slideIndex + 1 : undefined);
|
|
1298
|
-
if (slide) {
|
|
1299
|
-
return `Slide ${slide}`;
|
|
1300
|
-
}
|
|
1301
|
-
const archiveEntry = getContextString(metadata.archiveEntryPath) ?? getContextString(metadata.entryPath);
|
|
1302
|
-
if (archiveEntry) {
|
|
1303
|
-
return `Archive entry ${archiveEntry}`;
|
|
1304
|
-
}
|
|
1305
|
-
const emailKind = getContextString(metadata.emailKind);
|
|
1306
|
-
if (emailKind === "attachment") {
|
|
1307
|
-
const attachmentName = getContextString(metadata.attachmentName) ?? getAttachmentName(source, title);
|
|
1308
|
-
return attachmentName ? `Attachment ${attachmentName}` : "Attachment";
|
|
1309
|
-
}
|
|
1310
|
-
const mediaStart = formatMediaTimestamp(metadata.startMs);
|
|
1311
|
-
const mediaEnd = formatMediaTimestamp(metadata.endMs);
|
|
1312
|
-
if (mediaStart && mediaEnd) {
|
|
1313
|
-
return `Timestamp ${mediaStart} - ${mediaEnd}`;
|
|
1314
|
-
}
|
|
1315
|
-
if (mediaStart) {
|
|
1316
|
-
return `Timestamp ${mediaStart}`;
|
|
1424
|
+
var isErrorPayload = (value) => {
|
|
1425
|
+
if (!value || typeof value !== "object") {
|
|
1426
|
+
return false;
|
|
1317
1427
|
}
|
|
1318
|
-
return;
|
|
1428
|
+
return !("error" in value) || typeof value.error === "string";
|
|
1319
1429
|
};
|
|
1320
|
-
var
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
const mediaKind = getContextString(metadata.mediaKind);
|
|
1329
|
-
const transcriptSource = getContextString(metadata.transcriptSource);
|
|
1330
|
-
const pdfTextMode = getContextString(metadata.pdfTextMode);
|
|
1331
|
-
const ocrEngine = getContextString(metadata.ocrEngine);
|
|
1332
|
-
const labels = [
|
|
1333
|
-
pdfTextMode ? `PDF ${pdfTextMode}` : "",
|
|
1334
|
-
ocrEngine ? `OCR ${ocrEngine}` : "",
|
|
1335
|
-
mediaKind ? `Media ${mediaKind}` : "",
|
|
1336
|
-
transcriptSource ? `Transcript ${transcriptSource}` : "",
|
|
1337
|
-
threadTopic ? `Thread ${threadTopic}` : "",
|
|
1338
|
-
speaker ? `Speaker ${speaker}` : "",
|
|
1339
|
-
from ? `Sender ${from}` : "",
|
|
1340
|
-
sentAt ? `Sent ${sentAt}` : ""
|
|
1341
|
-
].filter((value) => value.length > 0);
|
|
1342
|
-
return labels.length > 0 ? labels.join(" \xB7 ") : undefined;
|
|
1430
|
+
var toErrorMessage = async (response) => {
|
|
1431
|
+
try {
|
|
1432
|
+
const payload = JSON.parse(await response.text());
|
|
1433
|
+
if (isErrorPayload(payload) && typeof payload.error === "string" && payload.error) {
|
|
1434
|
+
return payload.error;
|
|
1435
|
+
}
|
|
1436
|
+
} catch {}
|
|
1437
|
+
return `Request failed with status ${response.status}`;
|
|
1343
1438
|
};
|
|
1344
|
-
var
|
|
1345
|
-
|
|
1346
|
-
const
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
locatorLabel: buildLocatorLabel(source.metadata, source.source, source.title),
|
|
1359
|
-
metadata: source.metadata,
|
|
1360
|
-
provenanceLabel: buildProvenanceLabel(source.metadata),
|
|
1361
|
-
score: source.score,
|
|
1362
|
-
source: source.source,
|
|
1363
|
-
text: source.text,
|
|
1364
|
-
title: source.title
|
|
1365
|
-
});
|
|
1366
|
-
}
|
|
1367
|
-
return [...unique.values()].sort((left, right) => {
|
|
1368
|
-
if (right.score !== left.score) {
|
|
1369
|
-
return right.score - left.score;
|
|
1370
|
-
}
|
|
1371
|
-
return left.label.localeCompare(right.label);
|
|
1372
|
-
});
|
|
1373
|
-
};
|
|
1374
|
-
var buildExcerpt = (text, maxLength = 160) => {
|
|
1375
|
-
const normalized = text.replaceAll(/\s+/g, " ").trim();
|
|
1376
|
-
if (normalized.length <= maxLength) {
|
|
1377
|
-
return normalized;
|
|
1378
|
-
}
|
|
1379
|
-
return `${normalized.slice(0, Math.max(0, maxLength - 1)).trimEnd()}\u2026`;
|
|
1380
|
-
};
|
|
1381
|
-
var buildGroundingReferenceEvidenceLabel = (reference) => [reference.label, reference.locatorLabel, reference.contextLabel].filter((value) => Boolean(value && value.length > 0)).filter((value, index, values) => values.findIndex((entry) => entry === value) === index).join(" \xB7 ");
|
|
1382
|
-
var buildGroundingReferenceEvidenceSummary = (reference) => [
|
|
1383
|
-
reference.source ?? reference.title ?? reference.chunkId,
|
|
1384
|
-
reference.provenanceLabel
|
|
1385
|
-
].filter((value) => Boolean(value && value.length > 0)).join(" \xB7 ");
|
|
1386
|
-
var buildGroundedAnswerCitationDetail = (reference) => ({
|
|
1387
|
-
contextLabel: reference.contextLabel,
|
|
1388
|
-
evidenceLabel: buildGroundingReferenceEvidenceLabel(reference),
|
|
1389
|
-
evidenceSummary: buildGroundingReferenceEvidenceSummary(reference),
|
|
1390
|
-
excerpt: reference.excerpt,
|
|
1391
|
-
label: reference.label,
|
|
1392
|
-
locatorLabel: reference.locatorLabel,
|
|
1393
|
-
number: reference.number,
|
|
1394
|
-
provenanceLabel: reference.provenanceLabel,
|
|
1395
|
-
source: reference.source,
|
|
1396
|
-
title: reference.title
|
|
1397
|
-
});
|
|
1398
|
-
var buildRAGGroundedAnswer = (content, sources) => {
|
|
1399
|
-
const references = buildRAGGroundingReferences(sources);
|
|
1400
|
-
const referenceMap = new Map(references.map((reference) => [reference.number, reference]));
|
|
1401
|
-
const parts = [];
|
|
1402
|
-
const ungroundedReferenceNumbers = new Set;
|
|
1403
|
-
const citationPattern = /\[(\d+(?:\s*,\s*\d+)*)\]/g;
|
|
1404
|
-
let cursor = 0;
|
|
1405
|
-
for (const match of content.matchAll(citationPattern)) {
|
|
1406
|
-
const raw = match[0];
|
|
1407
|
-
const numbers = (match[1] ?? "").split(",").map((value) => Number.parseInt(value.trim(), 10)).filter((value) => Number.isInteger(value) && value > 0);
|
|
1408
|
-
const start = match.index ?? cursor;
|
|
1409
|
-
if (start > cursor) {
|
|
1410
|
-
parts.push({
|
|
1411
|
-
text: content.slice(cursor, start),
|
|
1412
|
-
type: "text"
|
|
1439
|
+
var createRAGClient = (options) => {
|
|
1440
|
+
const basePath = normalizeBasePath(options.path);
|
|
1441
|
+
const fetchImpl = options.fetch ?? fetch;
|
|
1442
|
+
return {
|
|
1443
|
+
async backends() {
|
|
1444
|
+
const response = await fetchImpl(`${basePath}/backends`);
|
|
1445
|
+
if (!response.ok) {
|
|
1446
|
+
throw new Error(await toErrorMessage(response));
|
|
1447
|
+
}
|
|
1448
|
+
return parseJson(response);
|
|
1449
|
+
},
|
|
1450
|
+
async clearIndex() {
|
|
1451
|
+
const response = await fetchImpl(`${basePath}/index`, {
|
|
1452
|
+
method: "DELETE"
|
|
1413
1453
|
});
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
for (const number of numbers) {
|
|
1417
|
-
if (!referenceMap.has(number)) {
|
|
1418
|
-
ungroundedReferenceNumbers.add(number);
|
|
1454
|
+
if (!response.ok) {
|
|
1455
|
+
throw new Error(await toErrorMessage(response));
|
|
1419
1456
|
}
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
}
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
}
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
})
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1457
|
+
return parseJson(response);
|
|
1458
|
+
},
|
|
1459
|
+
async createDocument(input) {
|
|
1460
|
+
const response = await fetchImpl(`${basePath}/documents`, {
|
|
1461
|
+
body: JSON.stringify(input),
|
|
1462
|
+
headers: jsonHeaders,
|
|
1463
|
+
method: "POST"
|
|
1464
|
+
});
|
|
1465
|
+
if (!response.ok) {
|
|
1466
|
+
return {
|
|
1467
|
+
error: await toErrorMessage(response),
|
|
1468
|
+
ok: false
|
|
1469
|
+
};
|
|
1470
|
+
}
|
|
1471
|
+
return parseJson(response);
|
|
1472
|
+
},
|
|
1473
|
+
async deleteDocument(id) {
|
|
1474
|
+
const response = await fetchImpl(`${basePath}/documents/${encodeURIComponent(id)}`, {
|
|
1475
|
+
method: "DELETE"
|
|
1476
|
+
});
|
|
1477
|
+
if (!response.ok) {
|
|
1478
|
+
return {
|
|
1479
|
+
error: await toErrorMessage(response),
|
|
1480
|
+
ok: false
|
|
1481
|
+
};
|
|
1482
|
+
}
|
|
1483
|
+
return parseJson(response);
|
|
1484
|
+
},
|
|
1485
|
+
async documentChunks(id) {
|
|
1486
|
+
const response = await fetchImpl(`${basePath}/documents/${encodeURIComponent(id)}/chunks`);
|
|
1487
|
+
if (!response.ok) {
|
|
1488
|
+
const error = await toErrorMessage(response);
|
|
1489
|
+
const errorResponse = {
|
|
1490
|
+
error,
|
|
1491
|
+
ok: false
|
|
1492
|
+
};
|
|
1493
|
+
return errorResponse;
|
|
1494
|
+
}
|
|
1495
|
+
return parseJson(response);
|
|
1496
|
+
},
|
|
1497
|
+
async documents(kind) {
|
|
1498
|
+
const query = kind ? `?kind=${encodeURIComponent(kind)}` : "";
|
|
1499
|
+
const response = await fetchImpl(`${basePath}/documents${query}`);
|
|
1500
|
+
if (!response.ok) {
|
|
1501
|
+
throw new Error(await toErrorMessage(response));
|
|
1502
|
+
}
|
|
1503
|
+
return parseJson(response);
|
|
1504
|
+
},
|
|
1505
|
+
async evaluate(input) {
|
|
1506
|
+
const response = await fetchImpl(`${basePath}/evaluate`, {
|
|
1507
|
+
body: JSON.stringify(input),
|
|
1508
|
+
headers: jsonHeaders,
|
|
1509
|
+
method: "POST"
|
|
1510
|
+
});
|
|
1511
|
+
if (!response.ok) {
|
|
1512
|
+
throw new Error(await toErrorMessage(response));
|
|
1513
|
+
}
|
|
1514
|
+
return parseJson(response);
|
|
1515
|
+
},
|
|
1516
|
+
async ingest(chunks) {
|
|
1517
|
+
const response = await fetchImpl(`${basePath}/ingest`, {
|
|
1518
|
+
body: JSON.stringify({ chunks }),
|
|
1519
|
+
headers: jsonHeaders,
|
|
1520
|
+
method: "POST"
|
|
1521
|
+
});
|
|
1522
|
+
if (!response.ok) {
|
|
1523
|
+
return {
|
|
1524
|
+
error: await toErrorMessage(response),
|
|
1525
|
+
ok: false
|
|
1526
|
+
};
|
|
1527
|
+
}
|
|
1528
|
+
return parseJson(response);
|
|
1529
|
+
},
|
|
1530
|
+
async ingestDocuments(input) {
|
|
1531
|
+
const response = await fetchImpl(`${basePath}/ingest`, {
|
|
1532
|
+
body: JSON.stringify(input),
|
|
1533
|
+
headers: jsonHeaders,
|
|
1534
|
+
method: "POST"
|
|
1535
|
+
});
|
|
1536
|
+
if (!response.ok) {
|
|
1537
|
+
return {
|
|
1538
|
+
error: await toErrorMessage(response),
|
|
1539
|
+
ok: false
|
|
1540
|
+
};
|
|
1541
|
+
}
|
|
1542
|
+
return parseJson(response);
|
|
1543
|
+
},
|
|
1544
|
+
async ingestUploads(input) {
|
|
1545
|
+
const response = await fetchImpl(`${basePath}/ingest`, {
|
|
1546
|
+
body: JSON.stringify(input),
|
|
1547
|
+
headers: jsonHeaders,
|
|
1548
|
+
method: "POST"
|
|
1549
|
+
});
|
|
1550
|
+
if (!response.ok) {
|
|
1551
|
+
return {
|
|
1552
|
+
error: await toErrorMessage(response),
|
|
1553
|
+
ok: false
|
|
1554
|
+
};
|
|
1555
|
+
}
|
|
1556
|
+
return parseJson(response);
|
|
1557
|
+
},
|
|
1558
|
+
async ingestUrls(input) {
|
|
1559
|
+
const response = await fetchImpl(`${basePath}/ingest`, {
|
|
1560
|
+
body: JSON.stringify(input),
|
|
1561
|
+
headers: jsonHeaders,
|
|
1562
|
+
method: "POST"
|
|
1563
|
+
});
|
|
1564
|
+
if (!response.ok) {
|
|
1565
|
+
return {
|
|
1566
|
+
error: await toErrorMessage(response),
|
|
1567
|
+
ok: false
|
|
1568
|
+
};
|
|
1569
|
+
}
|
|
1570
|
+
return parseJson(response);
|
|
1571
|
+
},
|
|
1572
|
+
async ops() {
|
|
1573
|
+
const response = await fetchImpl(`${basePath}/ops`);
|
|
1574
|
+
if (!response.ok) {
|
|
1575
|
+
throw new Error(await toErrorMessage(response));
|
|
1576
|
+
}
|
|
1577
|
+
return parseJson(response);
|
|
1578
|
+
},
|
|
1579
|
+
async syncSources() {
|
|
1580
|
+
const response = await fetchImpl(`${basePath}/sync`);
|
|
1581
|
+
if (!response.ok) {
|
|
1582
|
+
throw new Error(await toErrorMessage(response));
|
|
1583
|
+
}
|
|
1584
|
+
return parseJson(response);
|
|
1585
|
+
},
|
|
1586
|
+
async syncAllSources(options2) {
|
|
1587
|
+
const response = await fetchImpl(`${basePath}/sync`, {
|
|
1588
|
+
body: options2?.background === true ? JSON.stringify({ background: true }) : undefined,
|
|
1589
|
+
headers: options2?.background === true ? jsonHeaders : undefined,
|
|
1590
|
+
method: "POST"
|
|
1591
|
+
});
|
|
1592
|
+
if (!response.ok) {
|
|
1593
|
+
return {
|
|
1594
|
+
error: await toErrorMessage(response),
|
|
1595
|
+
ok: false
|
|
1596
|
+
};
|
|
1597
|
+
}
|
|
1598
|
+
return parseJson(response);
|
|
1599
|
+
},
|
|
1600
|
+
async syncSource(id, options2) {
|
|
1601
|
+
const response = await fetchImpl(`${basePath}/sync/${encodeURIComponent(id)}`, {
|
|
1602
|
+
body: options2?.background === true ? JSON.stringify({ background: true }) : undefined,
|
|
1603
|
+
headers: options2?.background === true ? jsonHeaders : undefined,
|
|
1604
|
+
method: "POST"
|
|
1605
|
+
});
|
|
1606
|
+
if (!response.ok) {
|
|
1607
|
+
return {
|
|
1608
|
+
error: await toErrorMessage(response),
|
|
1609
|
+
ok: false
|
|
1610
|
+
};
|
|
1611
|
+
}
|
|
1612
|
+
return parseJson(response);
|
|
1613
|
+
},
|
|
1614
|
+
async reindexDocument(id) {
|
|
1615
|
+
const response = await fetchImpl(`${basePath}/reindex/documents/${encodeURIComponent(id)}`, {
|
|
1616
|
+
method: "POST"
|
|
1617
|
+
});
|
|
1618
|
+
if (!response.ok) {
|
|
1619
|
+
return {
|
|
1620
|
+
error: await toErrorMessage(response),
|
|
1621
|
+
ok: false
|
|
1622
|
+
};
|
|
1623
|
+
}
|
|
1624
|
+
return parseJson(response);
|
|
1625
|
+
},
|
|
1626
|
+
async reindexSource(source) {
|
|
1627
|
+
const response = await fetchImpl(`${basePath}/reindex/source`, {
|
|
1628
|
+
body: JSON.stringify({ source }),
|
|
1629
|
+
headers: jsonHeaders,
|
|
1630
|
+
method: "POST"
|
|
1631
|
+
});
|
|
1632
|
+
if (!response.ok) {
|
|
1633
|
+
return {
|
|
1634
|
+
error: await toErrorMessage(response),
|
|
1635
|
+
ok: false
|
|
1636
|
+
};
|
|
1637
|
+
}
|
|
1638
|
+
return parseJson(response);
|
|
1639
|
+
},
|
|
1640
|
+
async reseed() {
|
|
1641
|
+
const response = await fetchImpl(`${basePath}/reseed`, {
|
|
1642
|
+
method: "POST"
|
|
1643
|
+
});
|
|
1644
|
+
if (!response.ok) {
|
|
1645
|
+
return {
|
|
1646
|
+
error: await toErrorMessage(response),
|
|
1647
|
+
ok: false
|
|
1648
|
+
};
|
|
1649
|
+
}
|
|
1650
|
+
return parseJson(response);
|
|
1651
|
+
},
|
|
1652
|
+
async reset() {
|
|
1653
|
+
const response = await fetchImpl(`${basePath}/reset`, {
|
|
1654
|
+
method: "POST"
|
|
1655
|
+
});
|
|
1656
|
+
if (!response.ok) {
|
|
1657
|
+
return {
|
|
1658
|
+
error: await toErrorMessage(response),
|
|
1659
|
+
ok: false
|
|
1660
|
+
};
|
|
1661
|
+
}
|
|
1662
|
+
return parseJson(response);
|
|
1663
|
+
},
|
|
1664
|
+
async search(input) {
|
|
1665
|
+
const response = await fetchImpl(`${basePath}/search`, {
|
|
1666
|
+
body: JSON.stringify(input),
|
|
1667
|
+
headers: jsonHeaders,
|
|
1668
|
+
method: "POST"
|
|
1669
|
+
});
|
|
1670
|
+
if (!response.ok) {
|
|
1671
|
+
throw new Error(await toErrorMessage(response));
|
|
1672
|
+
}
|
|
1673
|
+
const payload = await parseJson(response);
|
|
1674
|
+
if (!payload.ok) {
|
|
1675
|
+
throw new Error(payload.error ?? "RAG search failed");
|
|
1676
|
+
}
|
|
1677
|
+
return payload.results ?? [];
|
|
1678
|
+
},
|
|
1679
|
+
async status() {
|
|
1680
|
+
const response = await fetchImpl(`${basePath}/status`);
|
|
1681
|
+
if (!response.ok) {
|
|
1682
|
+
throw new Error(await toErrorMessage(response));
|
|
1683
|
+
}
|
|
1684
|
+
return parseJson(response);
|
|
1685
|
+
}
|
|
1610
1686
|
};
|
|
1611
1687
|
};
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
if (
|
|
1619
|
-
return
|
|
1688
|
+
|
|
1689
|
+
// src/angular/ai/rag-client.service.ts
|
|
1690
|
+
class RAGClientService {
|
|
1691
|
+
clients = new Map;
|
|
1692
|
+
client(path) {
|
|
1693
|
+
const existing = this.clients.get(path);
|
|
1694
|
+
if (existing) {
|
|
1695
|
+
return existing;
|
|
1620
1696
|
}
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
var buildSourceGroup = (source, key) => ({
|
|
1625
|
-
bestScore: source.score,
|
|
1626
|
-
chunks: [source],
|
|
1627
|
-
count: 1,
|
|
1628
|
-
key,
|
|
1629
|
-
label: buildSourceLabel(source),
|
|
1630
|
-
source: source.source,
|
|
1631
|
-
title: source.title
|
|
1632
|
-
});
|
|
1633
|
-
var updateSourceGroup = (groups, source) => {
|
|
1634
|
-
const key = buildSourceGroupKey(source);
|
|
1635
|
-
const existing = groups.get(key);
|
|
1636
|
-
if (!existing) {
|
|
1637
|
-
groups.set(key, buildSourceGroup(source, key));
|
|
1638
|
-
return;
|
|
1697
|
+
const created = createRAGClient({ path });
|
|
1698
|
+
this.clients.set(path, created);
|
|
1699
|
+
return created;
|
|
1639
1700
|
}
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
existing.chunks.push(source);
|
|
1643
|
-
};
|
|
1644
|
-
var getLatestAssistantMessage = (messages) => {
|
|
1645
|
-
for (let index = messages.length - 1;index >= 0; index -= 1) {
|
|
1646
|
-
const message = messages[index];
|
|
1647
|
-
if (message?.role === "assistant") {
|
|
1648
|
-
return message;
|
|
1649
|
-
}
|
|
1701
|
+
ingest(path, chunks) {
|
|
1702
|
+
return this.client(path).ingest(chunks);
|
|
1650
1703
|
}
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
var getLatestRAGSources = (messages) => getLatestAssistantMessage(messages)?.sources ?? [];
|
|
1654
|
-
var getLatestRetrievedMessage = (messages) => {
|
|
1655
|
-
for (let index = messages.length - 1;index >= 0; index -= 1) {
|
|
1656
|
-
const message = messages[index];
|
|
1657
|
-
if (message?.role === "assistant" && (typeof message.retrievedAt === "number" || (message.sources?.length ?? 0) > 0)) {
|
|
1658
|
-
return message;
|
|
1659
|
-
}
|
|
1704
|
+
ingestDocuments(path, input) {
|
|
1705
|
+
return this.client(path).ingestDocuments(input);
|
|
1660
1706
|
}
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
var resolveRAGStreamStage = ({
|
|
1664
|
-
error,
|
|
1665
|
-
isStreaming,
|
|
1666
|
-
messages
|
|
1667
|
-
}) => {
|
|
1668
|
-
if (error) {
|
|
1669
|
-
return "error";
|
|
1707
|
+
ingestUrls(path, input) {
|
|
1708
|
+
return this.client(path).ingestUrls(input);
|
|
1670
1709
|
}
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
return isStreaming ? "submitting" : "idle";
|
|
1710
|
+
ingestUploads(path, input) {
|
|
1711
|
+
return this.client(path).ingestUploads(input);
|
|
1674
1712
|
}
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
return "retrieving";
|
|
1713
|
+
search(path, input) {
|
|
1714
|
+
return this.client(path).search(input);
|
|
1678
1715
|
}
|
|
1679
|
-
|
|
1680
|
-
return
|
|
1716
|
+
evaluate(path, input) {
|
|
1717
|
+
return this.client(path).evaluate(input);
|
|
1681
1718
|
}
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
if (hasRetrieved && !hasContent) {
|
|
1685
|
-
return "retrieved";
|
|
1719
|
+
status(path) {
|
|
1720
|
+
return this.client(path).status();
|
|
1686
1721
|
}
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
hasRetrieved,
|
|
1729
|
-
hasSources,
|
|
1730
|
-
isAnswerStreaming,
|
|
1731
|
-
isComplete,
|
|
1732
|
-
isError,
|
|
1733
|
-
isRetrieved,
|
|
1734
|
-
isRetrieving,
|
|
1735
|
-
isRunning,
|
|
1736
|
-
latestAssistantMessage,
|
|
1737
|
-
progress,
|
|
1738
|
-
query: stream.send,
|
|
1739
|
-
retrieval,
|
|
1740
|
-
sourceGroups,
|
|
1741
|
-
sourceSummaries,
|
|
1742
|
-
sources,
|
|
1743
|
-
stage,
|
|
1744
|
-
workflow
|
|
1745
|
-
};
|
|
1722
|
+
ops(path) {
|
|
1723
|
+
return this.client(path).ops();
|
|
1724
|
+
}
|
|
1725
|
+
syncSources(path) {
|
|
1726
|
+
return this.client(path).syncSources();
|
|
1727
|
+
}
|
|
1728
|
+
syncAllSources(path, options) {
|
|
1729
|
+
return this.client(path).syncAllSources(options);
|
|
1730
|
+
}
|
|
1731
|
+
syncSource(path, id, options) {
|
|
1732
|
+
return this.client(path).syncSource(id, options);
|
|
1733
|
+
}
|
|
1734
|
+
documents(path, kind) {
|
|
1735
|
+
return this.client(path).documents(kind);
|
|
1736
|
+
}
|
|
1737
|
+
documentChunks(path, id) {
|
|
1738
|
+
return this.client(path).documentChunks(id);
|
|
1739
|
+
}
|
|
1740
|
+
createDocument(path, input) {
|
|
1741
|
+
return this.client(path).createDocument(input);
|
|
1742
|
+
}
|
|
1743
|
+
deleteDocument(path, id) {
|
|
1744
|
+
return this.client(path).deleteDocument(id);
|
|
1745
|
+
}
|
|
1746
|
+
reseed(path) {
|
|
1747
|
+
return this.client(path).reseed();
|
|
1748
|
+
}
|
|
1749
|
+
reset(path) {
|
|
1750
|
+
return this.client(path).reset();
|
|
1751
|
+
}
|
|
1752
|
+
reindexDocument(path, id) {
|
|
1753
|
+
return this.client(path).reindexDocument(id);
|
|
1754
|
+
}
|
|
1755
|
+
reindexSource(path, source) {
|
|
1756
|
+
return this.client(path).reindexSource(source);
|
|
1757
|
+
}
|
|
1758
|
+
backends(path) {
|
|
1759
|
+
return this.client(path).backends();
|
|
1760
|
+
}
|
|
1761
|
+
clearIndex(path) {
|
|
1762
|
+
return this.client(path).clearIndex();
|
|
1746
1763
|
}
|
|
1747
1764
|
}
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
],
|
|
1765
|
+
RAGClientService = __legacyDecorateClassTS([
|
|
1766
|
+
Injectable4({ providedIn: "root" })
|
|
1767
|
+
], RAGClientService);
|
|
1751
1768
|
export {
|
|
1752
|
-
|
|
1769
|
+
RAGWorkflowService,
|
|
1770
|
+
RAGStreamService,
|
|
1753
1771
|
RAGClientService,
|
|
1754
1772
|
AIStreamService
|
|
1755
1773
|
};
|
|
1756
1774
|
|
|
1757
|
-
//# debugId=
|
|
1775
|
+
//# debugId=0558F786B8740C0E64756E2164756E21
|
|
1758
1776
|
//# sourceMappingURL=index.js.map
|