@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.
Files changed (52) hide show
  1. package/dist/ai/client/index.js +5 -5
  2. package/dist/ai/client/index.js.map +1 -1
  3. package/dist/ai/index.js +4 -4
  4. package/dist/ai/index.js.map +1 -1
  5. package/dist/ai-client/angular/ai/index.js +880 -862
  6. package/dist/ai-client/react/ai/index.js +24 -24
  7. package/dist/ai-client/vue/ai/index.js +21 -21
  8. package/dist/angular/ai/index.js +873 -855
  9. package/dist/angular/ai/index.js.map +7 -6
  10. package/dist/angular/index.js +2 -2
  11. package/dist/angular/index.js.map +1 -1
  12. package/dist/angular/server.js +2 -2
  13. package/dist/angular/server.js.map +1 -1
  14. package/dist/build.js +2 -2
  15. package/dist/build.js.map +1 -1
  16. package/dist/index.js +2 -2
  17. package/dist/index.js.map +1 -1
  18. package/dist/react/ai/index.js +25 -25
  19. package/dist/react/ai/index.js.map +6 -6
  20. package/dist/src/ai/client/createRAGStream.d.ts +2 -0
  21. package/dist/src/ai/client/createRAGWorkflow.d.ts +3 -0
  22. package/dist/src/ai/client/index.d.ts +8 -7
  23. package/dist/src/ai/index.d.ts +5 -4
  24. package/dist/src/ai/rag/index.d.ts +2 -2
  25. package/dist/src/angular/ai/ai-rag-stream.service.d.ts +1 -1
  26. package/dist/src/angular/ai/ai-rag-workflow.service.d.ts +33 -0
  27. package/dist/src/angular/ai/index.d.ts +2 -1
  28. package/dist/src/react/ai/index.d.ts +6 -3
  29. package/dist/src/react/ai/useRAG.d.ts +3 -2
  30. package/dist/src/svelte/ai/createRAG.d.ts +5 -4
  31. package/dist/src/svelte/ai/createRAGStream.d.ts +1 -1
  32. package/dist/src/svelte/ai/createRAGStreamProgress.d.ts +1 -1
  33. package/dist/src/svelte/ai/createRAGWorkflow.d.ts +1 -1
  34. package/dist/src/svelte/ai/index.d.ts +4 -2
  35. package/dist/src/vue/ai/index.d.ts +5 -3
  36. package/dist/src/vue/ai/useRAG.d.ts +5 -4
  37. package/dist/src/vue/ai/useRAGStream.d.ts +1 -1
  38. package/dist/src/vue/ai/useRAGStreamProgress.d.ts +1 -1
  39. package/dist/src/vue/ai/useRAGWorkflow.d.ts +1 -1
  40. package/dist/svelte/ai/index.js +22 -22
  41. package/dist/svelte/ai/index.js.map +5 -5
  42. package/dist/vue/ai/index.js +22 -22
  43. package/dist/vue/ai/index.js.map +6 -6
  44. package/package.json +7 -7
  45. package/dist/src/ai/client/createRAGTransport.d.ts +0 -2
  46. package/dist/src/angular/ai/ai-rag-transport.service.d.ts +0 -1
  47. package/dist/src/react/ai/useRAGTransport.d.ts +0 -2
  48. package/dist/src/react/ai/useRAGTransportProgress.d.ts +0 -2
  49. package/dist/src/svelte/ai/createRAGTransport.d.ts +0 -2
  50. package/dist/src/svelte/ai/createRAGTransportProgress.d.ts +0 -2
  51. package/dist/src/vue/ai/useRAGTransport.d.ts +0 -2
  52. package/dist/src/vue/ai/useRAGTransportProgress.d.ts +0 -2
@@ -848,911 +848,929 @@ class AIStreamService {
848
848
  AIStreamService = __legacyDecorateClassTS([
849
849
  Injectable({ providedIn: "root" })
850
850
  ], AIStreamService);
851
- // src/angular/ai/rag-client.service.ts
852
- import { Injectable as Injectable2 } from "@angular/core";
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/client/ragClient.ts
855
- init_constants();
856
- var jsonHeaders = {
857
- "Content-Type": "application/json"
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 normalizeBasePath = (path) => path.endsWith("/") ? path.slice(0, UNFOUND_INDEX) : path;
860
- var parseJson = async (response) => {
861
- const payload = JSON.parse(await response.text());
862
- return payload;
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 isErrorPayload = (value) => {
865
- if (!value || typeof value !== "object") {
866
- return false;
882
+ var getAttachmentName = (source, title) => {
883
+ const sourceAttachment = source?.split("/").at(-1);
884
+ if (sourceAttachment && sourceAttachment.includes(".")) {
885
+ return sourceAttachment;
867
886
  }
868
- return !("error" in value) || typeof value.error === "string";
887
+ const titleAttachment = title?.split(" \xB7 ").at(-1);
888
+ if (titleAttachment && titleAttachment.includes(".")) {
889
+ return titleAttachment;
890
+ }
891
+ return;
869
892
  };
870
- var toErrorMessage = async (response) => {
871
- try {
872
- const payload = JSON.parse(await response.text());
873
- if (isErrorPayload(payload) && typeof payload.error === "string" && payload.error) {
874
- return payload.error;
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
- } catch {}
877
- return `Request failed with status ${response.status}`;
1017
+ return left.label.localeCompare(right.label);
1018
+ });
878
1019
  };
879
- var createRAGClient = (options) => {
880
- const basePath = normalizeBasePath(options.path);
881
- const fetchImpl = options.fetch ?? fetch;
882
- return {
883
- async backends() {
884
- const response = await fetchImpl(`${basePath}/backends`);
885
- if (!response.ok) {
886
- throw new Error(await toErrorMessage(response));
887
- }
888
- return parseJson(response);
889
- },
890
- async clearIndex() {
891
- const response = await fetchImpl(`${basePath}/index`, {
892
- method: "DELETE"
893
- });
894
- if (!response.ok) {
895
- throw new Error(await toErrorMessage(response));
896
- }
897
- return parseJson(response);
898
- },
899
- async createDocument(input) {
900
- const response = await fetchImpl(`${basePath}/documents`, {
901
- body: JSON.stringify(input),
902
- headers: jsonHeaders,
903
- method: "POST"
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
- if (!response.ok) {
906
- return {
907
- error: await toErrorMessage(response),
908
- ok: false
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 created = createRAGClient({ path });
1138
- this.clients.set(path, created);
1139
- return created;
1140
- }
1141
- ingest(path, chunks) {
1142
- return this.client(path).ingest(chunks);
1143
- }
1144
- ingestDocuments(path, input) {
1145
- return this.client(path).ingestDocuments(input);
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
- search(path, input) {
1154
- return this.client(path).search(input);
1078
+ if (cursor < content.length || parts.length === 0) {
1079
+ parts.push({
1080
+ text: content.slice(cursor),
1081
+ type: "text"
1082
+ });
1155
1083
  }
1156
- evaluate(path, input) {
1157
- return this.client(path).evaluate(input);
1158
- }
1159
- status(path) {
1160
- return this.client(path).status();
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
- ops(path) {
1163
- return this.client(path).ops();
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
- syncSources(path) {
1166
- return this.client(path).syncSources();
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
- syncAllSources(path, options) {
1169
- return this.client(path).syncAllSources(options);
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
- syncSource(path, id, options) {
1172
- return this.client(path).syncSource(id, options);
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
- documents(path, kind) {
1175
- return this.client(path).documents(kind);
1307
+ return;
1308
+ };
1309
+ var resolveRAGStreamStage = ({
1310
+ error,
1311
+ isStreaming,
1312
+ messages
1313
+ }) => {
1314
+ if (error) {
1315
+ return "error";
1176
1316
  }
1177
- documentChunks(path, id) {
1178
- return this.client(path).documentChunks(id);
1317
+ const assistantMessage = getLatestAssistantMessage(messages);
1318
+ if (!assistantMessage) {
1319
+ return isStreaming ? "submitting" : "idle";
1179
1320
  }
1180
- createDocument(path, input) {
1181
- return this.client(path).createDocument(input);
1321
+ const isRetrieving = typeof assistantMessage.retrievalStartedAt === "number" && typeof assistantMessage.retrievedAt !== "number";
1322
+ if (isRetrieving) {
1323
+ return "retrieving";
1182
1324
  }
1183
- deleteDocument(path, id) {
1184
- return this.client(path).deleteDocument(id);
1325
+ if (!isStreaming) {
1326
+ return "complete";
1185
1327
  }
1186
- reseed(path) {
1187
- return this.client(path).reseed();
1188
- }
1189
- reset(path) {
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
- clearIndex(path) {
1202
- return this.client(path).clearIndex();
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
- RAGClientService = __legacyDecorateClassTS([
1394
+ RAGStreamService = __legacyDecorateClassTS([
1206
1395
  Injectable2({ providedIn: "root" })
1207
- ], RAGClientService);
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/presentation.ts
1212
- var buildSourceGroupKey = (source) => source.source ?? source.title ?? source.chunkId;
1213
- var buildSourceLabel = (source) => source.source ?? source.title ?? source.chunkId;
1214
- var getContextNumber = (value) => typeof value === "number" && Number.isFinite(value) ? value : undefined;
1215
- var getContextString = (value) => typeof value === "string" && value.trim().length > 0 ? value.trim() : undefined;
1216
- var formatTimestampLabel = (value) => {
1217
- const timestamp = typeof value === "number" && Number.isFinite(value) ? value : typeof value === "string" ? Date.parse(value) : Number.NaN;
1218
- if (!Number.isFinite(timestamp)) {
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
- return;
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 buildContextLabel = (metadata) => {
1248
- if (!metadata) {
1249
- return;
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 buildLocatorLabel = (metadata, source, title) => {
1286
- if (!metadata) {
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 buildProvenanceLabel = (metadata) => {
1321
- if (!metadata) {
1322
- return;
1323
- }
1324
- const threadTopic = getContextString(metadata.threadTopic);
1325
- const from = getContextString(metadata.from);
1326
- const sentAt = formatTimestampLabel(metadata.sentAt) ?? formatTimestampLabel(metadata.receivedAt);
1327
- const speaker = getContextString(metadata.speaker);
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 buildRAGCitationReferenceMap = (citations) => Object.fromEntries(citations.map((citation, index) => [citation.chunkId, index + 1]));
1345
- var buildRAGCitations = (sources) => {
1346
- const unique = new Map;
1347
- for (const source of sources) {
1348
- const key = source.chunkId;
1349
- const existing = unique.get(key);
1350
- const hasBetterExisting = existing !== undefined && existing.score >= source.score;
1351
- if (hasBetterExisting)
1352
- continue;
1353
- unique.set(key, {
1354
- chunkId: source.chunkId,
1355
- contextLabel: buildContextLabel(source.metadata),
1356
- key,
1357
- label: buildSourceLabel(source),
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
- const resolvedReferences = numbers.map((number) => referenceMap.get(number)).filter((reference) => Boolean(reference));
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
- const unresolvedNumbers = numbers.filter((number) => !referenceMap.has(number));
1422
- parts.push({
1423
- referenceNumbers: numbers,
1424
- referenceDetails: resolvedReferences.map(buildGroundedAnswerCitationDetail),
1425
- references: resolvedReferences,
1426
- text: raw,
1427
- type: "citation",
1428
- unresolvedReferenceNumbers: unresolvedNumbers
1429
- });
1430
- cursor = start + raw.length;
1431
- }
1432
- if (cursor < content.length || parts.length === 0) {
1433
- parts.push({
1434
- text: content.slice(cursor),
1435
- type: "text"
1436
- });
1437
- }
1438
- const hasCitations = parts.some((part) => part.type === "citation");
1439
- const coverage = !hasCitations ? "ungrounded" : ungroundedReferenceNumbers.size === 0 ? "grounded" : references.length > 0 ? "partial" : "ungrounded";
1440
- return {
1441
- content,
1442
- coverage,
1443
- hasCitations,
1444
- parts,
1445
- references,
1446
- ungroundedReferenceNumbers: [...ungroundedReferenceNumbers].sort((left, right) => left - right)
1447
- };
1448
- };
1449
- var buildRAGGroundingReferences = (sources) => {
1450
- const citations = buildRAGCitations(sources);
1451
- const citationReferenceMap = buildRAGCitationReferenceMap(citations);
1452
- return citations.map((citation) => ({
1453
- chunkId: citation.chunkId,
1454
- contextLabel: buildContextLabel(citation.metadata),
1455
- excerpt: buildExcerpt(citation.text),
1456
- label: citation.label,
1457
- locatorLabel: citation.locatorLabel ?? buildLocatorLabel(citation.metadata, citation.source, citation.title),
1458
- metadata: citation.metadata,
1459
- number: citationReferenceMap[citation.chunkId] ?? 0,
1460
- provenanceLabel: citation.provenanceLabel ?? buildProvenanceLabel(citation.metadata),
1461
- score: citation.score,
1462
- source: citation.source,
1463
- text: citation.text,
1464
- title: citation.title
1465
- }));
1466
- };
1467
- var buildRAGRetrievedState = (messages) => {
1468
- const message = getLatestRetrievedMessage(messages);
1469
- if (!message) {
1470
- return null;
1471
- }
1472
- const sources = message.sources ?? [];
1473
- const groundedAnswer = buildRAGGroundedAnswer(message.content, sources);
1474
- return {
1475
- citationReferenceMap: buildRAGCitationReferenceMap(buildRAGCitations(sources)),
1476
- citations: buildRAGCitations(sources),
1477
- conversationId: message.conversationId,
1478
- groundedAnswer,
1479
- messageId: message.id,
1480
- retrievalDurationMs: message.retrievalDurationMs,
1481
- retrievalStartedAt: message.retrievalStartedAt,
1482
- retrievedAt: message.retrievedAt,
1483
- sourceGroups: buildRAGSourceGroups(sources),
1484
- sourceSummaries: buildRAGSourceSummaries(sources),
1485
- sources
1486
- };
1487
- };
1488
- var buildRAGSourceSummaries = (sources) => {
1489
- const sourceGroups = buildRAGSourceGroups(sources);
1490
- const citations = buildRAGCitations(sources);
1491
- const citationReferenceMap = buildRAGCitationReferenceMap(citations);
1492
- return sourceGroups.map((group) => {
1493
- const groupCitations = citations.filter((citation) => group.chunks.some((chunk) => chunk.chunkId === citation.chunkId));
1494
- const leadChunk = group.chunks.slice().sort((left, right) => right.score - left.score)[0];
1495
- return {
1496
- bestScore: group.bestScore,
1497
- citationNumbers: groupCitations.map((citation) => citationReferenceMap[citation.chunkId] ?? 0),
1498
- citations: groupCitations,
1499
- chunkIds: group.chunks.map((chunk) => chunk.chunkId),
1500
- contextLabel: buildContextLabel(leadChunk?.metadata),
1501
- count: group.count,
1502
- excerpt: buildExcerpt(leadChunk?.text ?? ""),
1503
- key: group.key,
1504
- label: group.label,
1505
- locatorLabel: buildLocatorLabel(leadChunk?.metadata, leadChunk?.source, leadChunk?.title),
1506
- provenanceLabel: buildProvenanceLabel(leadChunk?.metadata),
1507
- source: group.source,
1508
- title: group.title
1509
- };
1510
- });
1511
- };
1512
- var buildStreamProgressState = (messages) => {
1513
- const latestMessage = getLatestAssistantMessage(messages);
1514
- const retrieved = latestMessage ? buildRAGRetrievedState(messages) : undefined;
1515
- return {
1516
- conversationId: latestMessage?.conversationId,
1517
- latestMessage,
1518
- messageId: latestMessage?.id,
1519
- retrieved,
1520
- sourceCount: retrieved?.sources.length ?? latestMessage?.sources?.length ?? 0
1521
- };
1522
- };
1523
- var buildRAGStreamProgress = ({
1524
- error,
1525
- isStreaming,
1526
- messages
1527
- }) => {
1528
- const stage = resolveRAGStreamStage({
1529
- error,
1530
- isStreaming,
1531
- messages
1532
- });
1533
- const state = buildStreamProgressState(messages);
1534
- const hasSources = state.sourceCount > 0;
1535
- const hasRetrieved = stage === "retrieved" || state.retrieved !== undefined || state.latestMessage?.retrievedAt !== undefined;
1536
- const hasThinking = typeof state.latestMessage?.thinking === "string" && state.latestMessage.thinking.length > 0;
1537
- const hasToolCalls = (state.latestMessage?.toolCalls?.length ?? 0) > 0;
1538
- return {
1539
- conversationId: state.conversationId,
1540
- hasContent: typeof state.latestMessage?.content === "string" && state.latestMessage.content.length > 0,
1541
- hasRetrieved,
1542
- hasSources,
1543
- hasThinking,
1544
- hasToolCalls,
1545
- isComplete: stage === "complete",
1546
- isError: stage === "error",
1547
- isIdle: stage === "idle",
1548
- isRetrieved: stage === "retrieved",
1549
- isRetrieving: stage === "submitting" || stage === "retrieving",
1550
- isStreaming: stage === "streaming",
1551
- isSubmitting: stage === "submitting",
1552
- latestMessage: state.latestMessage,
1553
- messageId: state.messageId,
1554
- retrievalDurationMs: state.retrieved?.retrievalDurationMs,
1555
- retrievalStartedAt: state.retrieved?.retrievalStartedAt,
1556
- retrievedAt: state.retrieved?.retrievedAt,
1557
- sourceCount: state.sourceCount,
1558
- stage
1559
- };
1560
- };
1561
- var buildRAGAnswerWorkflowState = ({
1562
- error,
1563
- isStreaming,
1564
- messages
1565
- }) => {
1566
- const latestAssistantMessage = getLatestAssistantMessage(messages);
1567
- const sources = getLatestRAGSources(messages);
1568
- const sourceGroups = buildRAGSourceGroups(sources);
1569
- const citations = buildRAGCitations(sources);
1570
- const citationReferenceMap = buildRAGCitationReferenceMap(citations);
1571
- const sourceSummaries = buildRAGSourceSummaries(sources);
1572
- const groundingReferences = buildRAGGroundingReferences(sources);
1573
- const groundedAnswer = buildRAGGroundedAnswer(latestAssistantMessage?.content ?? "", sources);
1574
- const retrieval = buildRAGRetrievedState(messages);
1575
- const progress = buildRAGStreamProgress({
1576
- error,
1577
- isStreaming,
1578
- messages
1579
- });
1580
- return {
1581
- citationReferenceMap,
1582
- citations,
1583
- coverage: groundedAnswer.coverage,
1584
- error,
1585
- groundedAnswer,
1586
- groundingReferences,
1587
- hasCitations: groundedAnswer.hasCitations,
1588
- hasGrounding: groundingReferences.length > 0,
1589
- hasRetrieved: progress.hasRetrieved,
1590
- hasSources: sources.length > 0,
1591
- isAnswerStreaming: progress.isStreaming,
1592
- isComplete: progress.isComplete,
1593
- isError: progress.isError,
1594
- isIdle: progress.isIdle,
1595
- isRetrieved: progress.isRetrieved,
1596
- isRetrieving: progress.isRetrieving,
1597
- isRunning: progress.isSubmitting || progress.isRetrieving || progress.isStreaming,
1598
- isSubmitting: progress.isSubmitting,
1599
- latestAssistantMessage,
1600
- messages,
1601
- retrieval,
1602
- retrievalDurationMs: retrieval?.retrievalDurationMs,
1603
- retrievalStartedAt: retrieval?.retrievalStartedAt,
1604
- retrievedAt: retrieval?.retrievedAt,
1605
- sourceGroups,
1606
- sourceSummaries,
1607
- sources,
1608
- stage: progress.stage,
1609
- ungroundedReferenceNumbers: groundedAnswer.ungroundedReferenceNumbers
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
- var buildRAGSourceGroups = (sources) => {
1613
- const groups = new Map;
1614
- for (const source of sources) {
1615
- updateSourceGroup(groups, source);
1616
- }
1617
- return [...groups.values()].sort((left, right) => {
1618
- if (right.bestScore !== left.bestScore) {
1619
- return right.bestScore - left.bestScore;
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
- return left.label.localeCompare(right.label);
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
- existing.bestScore = Math.max(existing.bestScore, source.score);
1641
- existing.count += 1;
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
- return;
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
- return;
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
- const assistantMessage = getLatestAssistantMessage(messages);
1672
- if (!assistantMessage) {
1673
- return isStreaming ? "submitting" : "idle";
1710
+ ingestUploads(path, input) {
1711
+ return this.client(path).ingestUploads(input);
1674
1712
  }
1675
- const isRetrieving = typeof assistantMessage.retrievalStartedAt === "number" && typeof assistantMessage.retrievedAt !== "number";
1676
- if (isRetrieving) {
1677
- return "retrieving";
1713
+ search(path, input) {
1714
+ return this.client(path).search(input);
1678
1715
  }
1679
- if (!isStreaming) {
1680
- return "complete";
1716
+ evaluate(path, input) {
1717
+ return this.client(path).evaluate(input);
1681
1718
  }
1682
- const hasRetrieved = typeof assistantMessage.retrievedAt === "number";
1683
- const hasContent = assistantMessage.content.trim().length > 0 || assistantMessage.thinking?.trim().length || (assistantMessage.toolCalls?.length ?? 0) > 0 || (assistantMessage.images?.length ?? 0) > 0;
1684
- if (hasRetrieved && !hasContent) {
1685
- return "retrieved";
1719
+ status(path) {
1720
+ return this.client(path).status();
1686
1721
  }
1687
- return "streaming";
1688
- };
1689
-
1690
- // src/angular/ai/ai-rag-stream.service.ts
1691
- class RAGStreamService extends AIStreamService {
1692
- connect(path, conversationId) {
1693
- const stream = super.connect(path, conversationId);
1694
- const workflow = computed2(() => buildRAGAnswerWorkflowState({
1695
- error: stream.error(),
1696
- isStreaming: stream.isStreaming(),
1697
- messages: stream.messages()
1698
- }));
1699
- const progress = computed2(() => buildRAGStreamProgress({
1700
- error: stream.error(),
1701
- isStreaming: stream.isStreaming(),
1702
- messages: stream.messages()
1703
- }));
1704
- const latestAssistantMessage = computed2(() => workflow().latestAssistantMessage);
1705
- const sources = computed2(() => workflow().sources);
1706
- const sourceGroups = computed2(() => workflow().sourceGroups);
1707
- const citations = computed2(() => workflow().citations);
1708
- const sourceSummaries = computed2(() => workflow().sourceSummaries);
1709
- const citationReferenceMap = computed2(() => workflow().citationReferenceMap);
1710
- const retrieval = computed2(() => workflow().retrieval);
1711
- const groundedAnswer = computed2(() => workflow().groundedAnswer);
1712
- const groundingReferences = computed2(() => workflow().groundingReferences);
1713
- const hasRetrieved = computed2(() => workflow().hasRetrieved);
1714
- const hasSources = computed2(() => workflow().hasSources);
1715
- const isRetrieving = computed2(() => workflow().isRetrieving);
1716
- const isRetrieved = computed2(() => workflow().isRetrieved);
1717
- const isAnswerStreaming = computed2(() => workflow().isAnswerStreaming);
1718
- const isComplete = computed2(() => workflow().isComplete);
1719
- const isError = computed2(() => workflow().isError);
1720
- const isRunning = computed2(() => workflow().isRunning);
1721
- const stage = computed2(() => workflow().stage);
1722
- return {
1723
- ...stream,
1724
- citations,
1725
- citationReferenceMap,
1726
- groundedAnswer,
1727
- groundingReferences,
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
- RAGStreamService = __legacyDecorateClassTS([
1749
- Injectable3({ providedIn: "root" })
1750
- ], RAGStreamService);
1765
+ RAGClientService = __legacyDecorateClassTS([
1766
+ Injectable4({ providedIn: "root" })
1767
+ ], RAGClientService);
1751
1768
  export {
1752
- RAGStreamService as RAGTransportService,
1769
+ RAGWorkflowService,
1770
+ RAGStreamService,
1753
1771
  RAGClientService,
1754
1772
  AIStreamService
1755
1773
  };
1756
1774
 
1757
- //# debugId=AA31684A1A07ABA864756E2164756E21
1775
+ //# debugId=0558F786B8740C0E64756E2164756E21
1758
1776
  //# sourceMappingURL=index.js.map