@farukada/langchain-ts-rms 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (175) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +446 -0
  3. package/dist/app/freshness/evaluator.d.ts +23 -0
  4. package/dist/app/freshness/evaluator.d.ts.map +1 -0
  5. package/dist/app/freshness/evaluator.js +72 -0
  6. package/dist/app/freshness/evaluator.js.map +1 -0
  7. package/dist/app/governance/guardrails.d.ts +51 -0
  8. package/dist/app/governance/guardrails.d.ts.map +1 -0
  9. package/dist/app/governance/guardrails.js +68 -0
  10. package/dist/app/governance/guardrails.js.map +1 -0
  11. package/dist/app/graph/workflow.d.ts +1159 -0
  12. package/dist/app/graph/workflow.d.ts.map +1 -0
  13. package/dist/app/graph/workflow.js +468 -0
  14. package/dist/app/graph/workflow.js.map +1 -0
  15. package/dist/app/queryPlanning/planner.d.ts +18 -0
  16. package/dist/app/queryPlanning/planner.d.ts.map +1 -0
  17. package/dist/app/queryPlanning/planner.js +80 -0
  18. package/dist/app/queryPlanning/planner.js.map +1 -0
  19. package/dist/app/queryRewriting/rewriter.d.ts +32 -0
  20. package/dist/app/queryRewriting/rewriter.d.ts.map +1 -0
  21. package/dist/app/queryRewriting/rewriter.js +111 -0
  22. package/dist/app/queryRewriting/rewriter.js.map +1 -0
  23. package/dist/app/reranking/reranker.d.ts +27 -0
  24. package/dist/app/reranking/reranker.d.ts.map +1 -0
  25. package/dist/app/reranking/reranker.js +67 -0
  26. package/dist/app/reranking/reranker.js.map +1 -0
  27. package/dist/app/state/schema.d.ts +121 -0
  28. package/dist/app/state/schema.d.ts.map +1 -0
  29. package/dist/app/state/schema.js +88 -0
  30. package/dist/app/state/schema.js.map +1 -0
  31. package/dist/app/summarization/summarizationSchema.d.ts +34 -0
  32. package/dist/app/summarization/summarizationSchema.d.ts.map +1 -0
  33. package/dist/app/summarization/summarizationSchema.js +65 -0
  34. package/dist/app/summarization/summarizationSchema.js.map +1 -0
  35. package/dist/app/summarization/summarizer.d.ts +51 -0
  36. package/dist/app/summarization/summarizer.d.ts.map +1 -0
  37. package/dist/app/summarization/summarizer.js +181 -0
  38. package/dist/app/summarization/summarizer.js.map +1 -0
  39. package/dist/app/summarization/synthesisSchema.d.ts +16 -0
  40. package/dist/app/summarization/synthesisSchema.d.ts.map +1 -0
  41. package/dist/app/summarization/synthesisSchema.js +43 -0
  42. package/dist/app/summarization/synthesisSchema.js.map +1 -0
  43. package/dist/app/summarization/synthesizer.d.ts +21 -0
  44. package/dist/app/summarization/synthesizer.d.ts.map +1 -0
  45. package/dist/app/summarization/synthesizer.js +86 -0
  46. package/dist/app/summarization/synthesizer.js.map +1 -0
  47. package/dist/config/env.d.ts +49 -0
  48. package/dist/config/env.d.ts.map +1 -0
  49. package/dist/config/env.js +54 -0
  50. package/dist/config/env.js.map +1 -0
  51. package/dist/domain/contracts.d.ts +59 -0
  52. package/dist/domain/contracts.d.ts.map +1 -0
  53. package/dist/domain/contracts.js +52 -0
  54. package/dist/domain/contracts.js.map +1 -0
  55. package/dist/domain/ports.d.ts +63 -0
  56. package/dist/domain/ports.d.ts.map +1 -0
  57. package/dist/domain/ports.js +2 -0
  58. package/dist/domain/ports.js.map +1 -0
  59. package/dist/domain/researchUtils.d.ts +51 -0
  60. package/dist/domain/researchUtils.d.ts.map +1 -0
  61. package/dist/domain/researchUtils.js +85 -0
  62. package/dist/domain/researchUtils.js.map +1 -0
  63. package/dist/infra/chat/chatModelProvider.d.ts +4 -0
  64. package/dist/infra/chat/chatModelProvider.d.ts.map +1 -0
  65. package/dist/infra/chat/chatModelProvider.js +13 -0
  66. package/dist/infra/chat/chatModelProvider.js.map +1 -0
  67. package/dist/infra/checkpoint/checkpointerFactory.d.ts +38 -0
  68. package/dist/infra/checkpoint/checkpointerFactory.d.ts.map +1 -0
  69. package/dist/infra/checkpoint/checkpointerFactory.js +54 -0
  70. package/dist/infra/checkpoint/checkpointerFactory.js.map +1 -0
  71. package/dist/infra/content/contentExtractor.d.ts +58 -0
  72. package/dist/infra/content/contentExtractor.d.ts.map +1 -0
  73. package/dist/infra/content/contentExtractor.js +296 -0
  74. package/dist/infra/content/contentExtractor.js.map +1 -0
  75. package/dist/infra/embeddings/embeddingProvider.d.ts +4 -0
  76. package/dist/infra/embeddings/embeddingProvider.d.ts.map +1 -0
  77. package/dist/infra/embeddings/embeddingProvider.js +11 -0
  78. package/dist/infra/embeddings/embeddingProvider.js.map +1 -0
  79. package/dist/infra/healthCheck.d.ts +23 -0
  80. package/dist/infra/healthCheck.d.ts.map +1 -0
  81. package/dist/infra/healthCheck.js +57 -0
  82. package/dist/infra/healthCheck.js.map +1 -0
  83. package/dist/infra/observability/tokenCounter.d.ts +30 -0
  84. package/dist/infra/observability/tokenCounter.d.ts.map +1 -0
  85. package/dist/infra/observability/tokenCounter.js +46 -0
  86. package/dist/infra/observability/tokenCounter.js.map +1 -0
  87. package/dist/infra/observability/tracing.d.ts +38 -0
  88. package/dist/infra/observability/tracing.d.ts.map +1 -0
  89. package/dist/infra/observability/tracing.js +92 -0
  90. package/dist/infra/observability/tracing.js.map +1 -0
  91. package/dist/infra/rateLimit/circuitBreaker.d.ts +54 -0
  92. package/dist/infra/rateLimit/circuitBreaker.d.ts.map +1 -0
  93. package/dist/infra/rateLimit/circuitBreaker.js +97 -0
  94. package/dist/infra/rateLimit/circuitBreaker.js.map +1 -0
  95. package/dist/infra/rateLimit/rateLimiter.d.ts +42 -0
  96. package/dist/infra/rateLimit/rateLimiter.d.ts.map +1 -0
  97. package/dist/infra/rateLimit/rateLimiter.js +89 -0
  98. package/dist/infra/rateLimit/rateLimiter.js.map +1 -0
  99. package/dist/infra/search/searxngClient.d.ts +29 -0
  100. package/dist/infra/search/searxngClient.d.ts.map +1 -0
  101. package/dist/infra/search/searxngClient.js +85 -0
  102. package/dist/infra/search/searxngClient.js.map +1 -0
  103. package/dist/infra/search/urlBlocklist.d.ts +28 -0
  104. package/dist/infra/search/urlBlocklist.d.ts.map +1 -0
  105. package/dist/infra/search/urlBlocklist.js +78 -0
  106. package/dist/infra/search/urlBlocklist.js.map +1 -0
  107. package/dist/infra/vector/qdrantClient.d.ts +18 -0
  108. package/dist/infra/vector/qdrantClient.d.ts.map +1 -0
  109. package/dist/infra/vector/qdrantClient.js +82 -0
  110. package/dist/infra/vector/qdrantClient.js.map +1 -0
  111. package/dist/infra/vector/researchRepository.d.ts +39 -0
  112. package/dist/infra/vector/researchRepository.d.ts.map +1 -0
  113. package/dist/infra/vector/researchRepository.js +294 -0
  114. package/dist/infra/vector/researchRepository.js.map +1 -0
  115. package/dist/lib/helpers.d.ts +50 -0
  116. package/dist/lib/helpers.d.ts.map +1 -0
  117. package/dist/lib/helpers.js +124 -0
  118. package/dist/lib/helpers.js.map +1 -0
  119. package/dist/lib/index.d.ts +65 -0
  120. package/dist/lib/index.d.ts.map +1 -0
  121. package/dist/lib/index.js +61 -0
  122. package/dist/lib/index.js.map +1 -0
  123. package/dist/lib/rmsTool.d.ts +28 -0
  124. package/dist/lib/rmsTool.d.ts.map +1 -0
  125. package/dist/lib/rmsTool.js +79 -0
  126. package/dist/lib/rmsTool.js.map +1 -0
  127. package/dist/lib/schemas/lifecycleSchemas.d.ts +42 -0
  128. package/dist/lib/schemas/lifecycleSchemas.d.ts.map +1 -0
  129. package/dist/lib/schemas/lifecycleSchemas.js +176 -0
  130. package/dist/lib/schemas/lifecycleSchemas.js.map +1 -0
  131. package/dist/lib/schemas/researchSchemas.d.ts +23 -0
  132. package/dist/lib/schemas/researchSchemas.d.ts.map +1 -0
  133. package/dist/lib/schemas/researchSchemas.js +83 -0
  134. package/dist/lib/schemas/researchSchemas.js.map +1 -0
  135. package/dist/lib/tools/deleteResearch.d.ts +19 -0
  136. package/dist/lib/tools/deleteResearch.d.ts.map +1 -0
  137. package/dist/lib/tools/deleteResearch.js +37 -0
  138. package/dist/lib/tools/deleteResearch.js.map +1 -0
  139. package/dist/lib/tools/getDatetime.d.ts +7 -0
  140. package/dist/lib/tools/getDatetime.d.ts.map +1 -0
  141. package/dist/lib/tools/getDatetime.js +26 -0
  142. package/dist/lib/tools/getDatetime.js.map +1 -0
  143. package/dist/lib/tools/getResearch.d.ts +19 -0
  144. package/dist/lib/tools/getResearch.d.ts.map +1 -0
  145. package/dist/lib/tools/getResearch.js +32 -0
  146. package/dist/lib/tools/getResearch.js.map +1 -0
  147. package/dist/lib/tools/listResearch.d.ts +25 -0
  148. package/dist/lib/tools/listResearch.d.ts.map +1 -0
  149. package/dist/lib/tools/listResearch.js +41 -0
  150. package/dist/lib/tools/listResearch.js.map +1 -0
  151. package/dist/lib/tools/refreshResearch.d.ts +27 -0
  152. package/dist/lib/tools/refreshResearch.d.ts.map +1 -0
  153. package/dist/lib/tools/refreshResearch.js +81 -0
  154. package/dist/lib/tools/refreshResearch.js.map +1 -0
  155. package/dist/lib/tools/research.d.ts +108 -0
  156. package/dist/lib/tools/research.d.ts.map +1 -0
  157. package/dist/lib/tools/research.js +273 -0
  158. package/dist/lib/tools/research.js.map +1 -0
  159. package/dist/lib/tools/searchResearch.d.ts +25 -0
  160. package/dist/lib/tools/searchResearch.d.ts.map +1 -0
  161. package/dist/lib/tools/searchResearch.js +45 -0
  162. package/dist/lib/tools/searchResearch.js.map +1 -0
  163. package/dist/lib/types.d.ts +51 -0
  164. package/dist/lib/types.d.ts.map +1 -0
  165. package/dist/lib/types.js +2 -0
  166. package/dist/lib/types.js.map +1 -0
  167. package/dist/mcp/index.d.ts +12 -0
  168. package/dist/mcp/index.d.ts.map +1 -0
  169. package/dist/mcp/index.js +12 -0
  170. package/dist/mcp/index.js.map +1 -0
  171. package/dist/mcp/server.d.ts +45 -0
  172. package/dist/mcp/server.d.ts.map +1 -0
  173. package/dist/mcp/server.js +440 -0
  174. package/dist/mcp/server.js.map +1 -0
  175. package/package.json +132 -0
@@ -0,0 +1,181 @@
1
+ import { HumanMessage, SystemMessage } from "@langchain/core/messages";
2
+ import { logInfo, logWarn } from "../../infra/observability/tracing.js";
3
+ import { SourceSummaryOutputSchema } from "./summarizationSchema.js";
4
+ import { batchExtractContent } from "../../infra/content/contentExtractor.js";
5
+ // ── Helpers ───────────────────────────────────────────────────────
6
+ /**
7
+ * Normalizes tags: lowercase, replace spaces with hyphens, deduplicate, sort.
8
+ * Ensures consistent tag format across all sources.
9
+ */
10
+ export function normalizeTags(tags) {
11
+ const normalized = new Set(tags.map((t) => t.trim().toLowerCase().replace(/\s+/g, "-")).filter((t) => t.length > 0));
12
+ return [...normalized].sort();
13
+ }
14
+ // ── Constants ────────────────────────────────────────────────────
15
+ /** Maximum characters of extracted content to include per source in the prompt. */
16
+ const MAX_CHARS_PER_SOURCE = 8000;
17
+ /** Minimum acceptable length for a keyTakeaways field (chars). Below this, retry once. */
18
+ const MIN_TAKEAWAY_LENGTH = 200;
19
+ // ── Prompt ────────────────────────────────────────────────────────
20
+ const SYSTEM_PROMPT = `You are a research extraction assistant. Your takeaways feed into a synthesis step that produces a research report for developers.
21
+
22
+ Before extracting, consider: what specific facts does this source contribute, and what concrete details would a developer find actionable?
23
+
24
+ Guidelines:
25
+ 1. Focus on facts, techniques, tools, numbers, and actionable insights relevant to the research subject.
26
+ 2. Be concrete — include names, version numbers, code patterns, and configuration values.
27
+ 3. Write substantive multi-paragraph extractions covering all noteworthy information.
28
+ 4. If the source has no useful information, write "No relevant information found." and set relevance to 0.
29
+ 5. Score relevance generously: 0.7-1.0 for on-topic sources, 0.4-0.7 for partially relevant, below 0.3 only for truly off-topic.`;
30
+ // ── Core logic ──────────────────────────────────────────────────────
31
+ /**
32
+ * Summarizes a single source via a focused LLM call.
33
+ *
34
+ * If the LLM call fails or produces a thin takeaway, retries once with a
35
+ * reinforced prompt. If both attempts fail, returns a degraded fallback
36
+ * using the snippet.
37
+ */
38
+ async function summarizeSingleSource(subject, searchResult, contentText, wasExtracted, sourceIndex, totalSources, chatModel) {
39
+ const contentLabel = wasExtracted ? "Full Page Content" : "Snippet";
40
+ const truncatedText = contentText.slice(0, MAX_CHARS_PER_SOURCE);
41
+ const humanMsg = `Research subject:\n<subject>\n${subject}\n</subject>\n\n` +
42
+ `--- Source ---\n` +
43
+ `Title: ${searchResult.title}\n` +
44
+ `URL: ${searchResult.url}\n\n` +
45
+ `<source_content type="${contentLabel}">\n${truncatedText}\n</source_content>\n\n` +
46
+ `Extract key takeaways from this source.`;
47
+ try {
48
+ const structuredModel = chatModel.withStructuredOutput(SourceSummaryOutputSchema, {
49
+ method: "jsonSchema",
50
+ name: "source_summary",
51
+ });
52
+ let result = await structuredModel.invoke([
53
+ new SystemMessage(SYSTEM_PROMPT),
54
+ new HumanMessage(humanMsg),
55
+ ]);
56
+ // Quality gate: if takeaway is too thin, retry once with reinforced prompt
57
+ if (result.keyTakeaways.trim().length < MIN_TAKEAWAY_LENGTH) {
58
+ logWarn(`Source [${String(sourceIndex + 1)}/${String(totalSources)}] takeaway too thin, retrying`, {
59
+ node: "summarizer",
60
+ url: searchResult.url,
61
+ takeawayLength: result.keyTakeaways.trim().length,
62
+ });
63
+ const retryMsg = humanMsg +
64
+ "\n\nIMPORTANT: Your previous response had a very short takeaway. " +
65
+ "Write a substantially longer extraction with much more detail. " +
66
+ "Extract specific facts, version numbers, code patterns, and actionable advice from the source.";
67
+ result = await structuredModel.invoke([
68
+ new SystemMessage(SYSTEM_PROMPT),
69
+ new HumanMessage(retryMsg),
70
+ ]);
71
+ }
72
+ logInfo(`Source [${String(sourceIndex + 1)}/${String(totalSources)}] summarized`, {
73
+ node: "summarizer",
74
+ url: searchResult.url,
75
+ takeawayLength: result.keyTakeaways.trim().length,
76
+ relevance: result.relevance,
77
+ });
78
+ return {
79
+ url: searchResult.url,
80
+ title: searchResult.title,
81
+ keyTakeaways: result.keyTakeaways.trim(),
82
+ relevance: Math.min(1, Math.max(0, result.relevance ?? 0.5)),
83
+ tags: result.tags ?? [],
84
+ language: result.language ?? "en",
85
+ };
86
+ }
87
+ catch (err) {
88
+ logWarn(`Source [${String(sourceIndex + 1)}/${String(totalSources)}] summarization failed, using degraded fallback`, {
89
+ node: "summarizer",
90
+ url: searchResult.url,
91
+ error: err instanceof Error ? err.message : String(err),
92
+ });
93
+ // Degraded fallback: use the snippet as-is with zero relevance
94
+ return {
95
+ url: searchResult.url,
96
+ title: searchResult.title,
97
+ keyTakeaways: searchResult.snippet,
98
+ relevance: 0,
99
+ tags: [],
100
+ language: "en",
101
+ };
102
+ }
103
+ }
104
+ /**
105
+ * Summarizes search results by making ONE focused LLM call per source.
106
+ *
107
+ * Each source gets full page content extracted (when available, via streaming
108
+ * with byte-limit protection) or falls back to SearXNG snippets. Content is
109
+ * truncated to {@link MAX_CHARS_PER_SOURCE} chars per source.
110
+ *
111
+ * Individual source failures are isolated — a failed LLM call for one source
112
+ * does not affect the others. Failed sources fall back to snippet-based
113
+ * degraded entries with `relevance: 0`.
114
+ */
115
+ export async function summarizeSearchResults(subject, searchResults, chatModel) {
116
+ logInfo("Summarizing results (per-source sequential)", {
117
+ node: "summarizer",
118
+ researchId: subject,
119
+ sourceCount: searchResults.length,
120
+ });
121
+ if (searchResults.length === 0) {
122
+ logWarn("No search results to summarize", {
123
+ node: "summarizer",
124
+ researchId: subject,
125
+ });
126
+ throw new Error("No search results to summarize");
127
+ }
128
+ // Extract full page content for all sources (with snippet fallback)
129
+ const extractedContents = await batchExtractContent(searchResults.map((sr) => ({ url: sr.url, snippet: sr.snippet })));
130
+ // Build extraction breakdown for debugging
131
+ const extractionBreakdown = extractedContents.map((c, i) => ({
132
+ url: searchResults[i]?.url ?? "",
133
+ method: c.extractionMethod,
134
+ extractedLength: c.extractedLength,
135
+ }));
136
+ // Process each source sequentially with its own focused LLM call
137
+ const sourceSummaries = [];
138
+ for (let i = 0; i < searchResults.length; i++) {
139
+ const sr = searchResults[i];
140
+ const content = extractedContents[i];
141
+ const summary = await summarizeSingleSource(subject, sr, content.text, content.wasExtracted, i, searchResults.length, chatModel);
142
+ sourceSummaries.push(summary);
143
+ }
144
+ const successCount = sourceSummaries.filter((s) => s.relevance > 0).length;
145
+ logInfo("Per-source summarization complete", {
146
+ node: "summarizer",
147
+ researchId: subject,
148
+ successCount,
149
+ degradedCount: sourceSummaries.length - successCount,
150
+ totalSources: searchResults.length,
151
+ });
152
+ return buildSummarizationResult(sourceSummaries, extractionBreakdown);
153
+ }
154
+ /**
155
+ * Computes aggregate confidence, tags, and language from per-source summaries.
156
+ */
157
+ function buildSummarizationResult(sourceSummaries, extractionBreakdown = []) {
158
+ // Weighted confidence: only relevant sources count, weighted by relevance.
159
+ // NaN >= 0.3 is false, so NaN-relevance sources are excluded by the filter.
160
+ // The final Number.isFinite guard catches any remaining arithmetic edge cases.
161
+ const relevantSources = sourceSummaries.filter((s) => Number.isFinite(s.relevance) && s.relevance >= 0.3);
162
+ const rawConfidence = relevantSources.length > 0
163
+ ? Math.min(1, Math.max(0.1, relevantSources.reduce((sum, s) => sum + s.relevance, 0) / relevantSources.length))
164
+ : 0.1;
165
+ const overallConfidence = Number.isFinite(rawConfidence) ? rawConfidence : 0.1;
166
+ const allTags = normalizeTags(sourceSummaries.flatMap((s) => s.tags));
167
+ // Majority-vote language
168
+ const langCounts = new Map();
169
+ for (const s of sourceSummaries) {
170
+ langCounts.set(s.language, (langCounts.get(s.language) ?? 0) + 1);
171
+ }
172
+ const language = [...langCounts.entries()].sort((a, b) => b[1] - a[1])[0]?.[0] ?? "en";
173
+ return {
174
+ sourceSummaries,
175
+ overallConfidence: Math.round(overallConfidence * 100) / 100,
176
+ tags: allTags,
177
+ language,
178
+ extractionBreakdown,
179
+ };
180
+ }
181
+ //# sourceMappingURL=summarizer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"summarizer.js","sourceRoot":"","sources":["../../../src/app/summarization/summarizer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import { z } from "zod/v4";
2
+ /**
3
+ * Schema for structured LLM output when synthesizing all per-source
4
+ * takeaways into a unified research summary.
5
+ *
6
+ * Used with `chatModel.withStructuredOutput(SynthesisOutputSchema)`.
7
+ * This is a single LLM call that receives all relevant takeaways
8
+ * and produces a comprehensive, theme-organized research report.
9
+ */
10
+ export declare const SynthesisOutputSchema: z.ZodObject<{
11
+ synthesizedSummary: z.ZodString;
12
+ keyFindings: z.ZodArray<z.ZodString>;
13
+ limitations: z.ZodDefault<z.ZodArray<z.ZodString>>;
14
+ }, z.core.$strip>;
15
+ export type SynthesisOutput = z.infer<typeof SynthesisOutputSchema>;
16
+ //# sourceMappingURL=synthesisSchema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"synthesisSchema.d.ts","sourceRoot":"","sources":["../../../src/app/summarization/synthesisSchema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AAE3B;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB;;;;iBAmChC,CAAC;AAEH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC"}
@@ -0,0 +1,43 @@
1
+ import { z } from "zod/v4";
2
+ /**
3
+ * Schema for structured LLM output when synthesizing all per-source
4
+ * takeaways into a unified research summary.
5
+ *
6
+ * Used with `chatModel.withStructuredOutput(SynthesisOutputSchema)`.
7
+ * This is a single LLM call that receives all relevant takeaways
8
+ * and produces a comprehensive, theme-organized research report.
9
+ */
10
+ export const SynthesisOutputSchema = z.object({
11
+ synthesizedSummary: z.string().meta({
12
+ description: "A comprehensive research summary organized by themes (NOT by source). " +
13
+ "Write 5-10 paragraphs covering: key concepts, practical techniques, " +
14
+ "tools/frameworks mentioned, best practices, trade-offs, and implementation details. " +
15
+ "Include specific facts, numbers, version references, code patterns, and actionable advice. " +
16
+ "Go deep — write flowing prose.",
17
+ examples: [
18
+ "State management in LangGraph centers on the StateGraph API, introduced in v0.2 as a replacement for the legacy MessageGraph. " +
19
+ "Persistence is handled through a pluggable checkpointer interface with MemorySaver for development and PostgresSaver for production.",
20
+ ],
21
+ }),
22
+ keyFindings: z
23
+ .array(z.string())
24
+ .max(15)
25
+ .meta({
26
+ description: "5-15 crisp, actionable key findings distilled from the research. " +
27
+ "Each finding should be a single sentence with specific details (names, versions, numbers). " +
28
+ "Cover all major insights — do not artificially limit the count.",
29
+ examples: [
30
+ "TypeScript strict mode catches 15-20% more bugs at compile time",
31
+ "Use path aliases in tsconfig.json to avoid deeply nested relative imports",
32
+ ],
33
+ }),
34
+ limitations: z
35
+ .array(z.string())
36
+ .default([])
37
+ .meta({
38
+ description: "Known gaps, caveats, or limitations in the research. " +
39
+ "E.g. 'Most sources focus on Node.js backend; frontend patterns are underrepresented.' " +
40
+ "Leave empty if no significant limitations.",
41
+ }),
42
+ });
43
+ //# sourceMappingURL=synthesisSchema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"synthesisSchema.js","sourceRoot":"","sources":["../../../src/app/summarization/synthesisSchema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AAE3B;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC5C,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC;QAClC,WAAW,EACT,wEAAwE;YACxE,sEAAsE;YACtE,sFAAsF;YACtF,6FAA6F;YAC7F,gCAAgC;QAClC,QAAQ,EAAE;YACR,gIAAgI;gBAC9H,sIAAsI;SACzI;KACF,CAAC;IACF,WAAW,EAAE,CAAC;SACX,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;SACjB,GAAG,CAAC,EAAE,CAAC;SACP,IAAI,CAAC;QACJ,WAAW,EACT,mEAAmE;YACnE,6FAA6F;YAC7F,iEAAiE;QACnE,QAAQ,EAAE;YACR,iEAAiE;YACjE,2EAA2E;SAC5E;KACF,CAAC;IACJ,WAAW,EAAE,CAAC;SACX,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;SACjB,OAAO,CAAC,EAAE,CAAC;SACX,IAAI,CAAC;QACJ,WAAW,EACT,uDAAuD;YACvD,wFAAwF;YACxF,4CAA4C;KAC/C,CAAC;CACL,CAAC,CAAC"}
@@ -0,0 +1,21 @@
1
+ import type { BaseChatModel } from "@langchain/core/language_models/chat_models";
2
+ import type { SourceSummary } from "./summarizer.js";
3
+ /** Result of synthesizing per-source takeaways into a unified report. */
4
+ export interface SynthesisResult {
5
+ /** The synthesized multi-paragraph research summary. */
6
+ synthesizedSummary: string;
7
+ /** 3-7 crisp, actionable key findings. */
8
+ keyFindings: string[];
9
+ /** Known gaps or limitations in the research. */
10
+ limitations: string[];
11
+ }
12
+ /**
13
+ * Synthesizes per-source takeaways into a unified, theme-organized
14
+ * research report using a single LLM call.
15
+ *
16
+ * Only sources with relevance ≥ 0.3 are included.
17
+ * This produces a qualitatively superior summary compared to
18
+ * simple concatenation of per-source takeaways.
19
+ */
20
+ export declare function synthesizeSummary(subject: string, sourceSummaries: SourceSummary[], chatModel: BaseChatModel): Promise<SynthesisResult>;
21
+ //# sourceMappingURL=synthesizer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"synthesizer.d.ts","sourceRoot":"","sources":["../../../src/app/summarization/synthesizer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6CAA6C,CAAC;AAEjF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAMrD,yEAAyE;AACzE,MAAM,WAAW,eAAe;IAC9B,wDAAwD;IACxD,kBAAkB,EAAE,MAAM,CAAC;IAC3B,0CAA0C;IAC1C,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,iDAAiD;IACjD,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAmBD;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,MAAM,EACf,eAAe,EAAE,aAAa,EAAE,EAChC,SAAS,EAAE,aAAa,GACvB,OAAO,CAAC,eAAe,CAAC,CAwE1B"}
@@ -0,0 +1,86 @@
1
+ import { HumanMessage, SystemMessage } from "@langchain/core/messages";
2
+ import { SynthesisOutputSchema } from "./synthesisSchema.js";
3
+ import { logInfo, logWarn, logError, ErrorCodes } from "../../infra/observability/tracing.js";
4
+ // ── Prompt ────────────────────────────────────────────────────────
5
+ const SYSTEM_PROMPT = `You are a senior research analyst producing final research reports for developers and technical decision-makers.
6
+
7
+ Before writing, consider: what themes emerge across sources, and where do sources agree or contradict?
8
+
9
+ Guidelines:
10
+ 1. Organize by theme, grouping related insights from different sources together.
11
+ 2. Write flowing prose with exhaustive detail — specific facts, numbers, code patterns, and actionable advice.
12
+ 3. Highlight consensus and contradictions across sources.
13
+ 4. Synthesize into a unified narrative — the reader should not be aware of individual source boundaries.`;
14
+ /** Minimum relevance threshold for including a source in synthesis. */
15
+ const MIN_RELEVANCE_FOR_SYNTHESIS = 0.3;
16
+ // ── Core logic ──────────────────────────────────────────────────────
17
+ /**
18
+ * Synthesizes per-source takeaways into a unified, theme-organized
19
+ * research report using a single LLM call.
20
+ *
21
+ * Only sources with relevance ≥ 0.3 are included.
22
+ * This produces a qualitatively superior summary compared to
23
+ * simple concatenation of per-source takeaways.
24
+ */
25
+ export async function synthesizeSummary(subject, sourceSummaries, chatModel) {
26
+ const relevantSources = sourceSummaries.filter((s) => s.relevance >= MIN_RELEVANCE_FOR_SYNTHESIS);
27
+ if (relevantSources.length === 0) {
28
+ logWarn("No relevant sources for synthesis", {
29
+ node: "synthesizer",
30
+ researchId: subject,
31
+ totalSources: sourceSummaries.length,
32
+ });
33
+ return {
34
+ synthesizedSummary: "No sufficiently relevant sources were found to produce a research synthesis.",
35
+ keyFindings: [],
36
+ limitations: ["All sources had low relevance to the research subject."],
37
+ };
38
+ }
39
+ logInfo("Synthesizing research summary", {
40
+ node: "synthesizer",
41
+ researchId: subject,
42
+ relevantSources: relevantSources.length,
43
+ totalSources: sourceSummaries.length,
44
+ });
45
+ const takeawaysBlock = relevantSources
46
+ .map((s, i) => `[Source ${String(i + 1)}] (relevance: ${String(s.relevance)}, tags: ${s.tags.join(", ")})\n${s.keyTakeaways}`)
47
+ .join("\n\n");
48
+ const humanMsg = `Research subject:\n<subject>\n${subject}\n</subject>\n\n` +
49
+ `Total sources analyzed: ${String(sourceSummaries.length)} ` +
50
+ `(${String(relevantSources.length)} relevant)\n\n` +
51
+ `<source_takeaways>\n${takeawaysBlock}\n</source_takeaways>\n\n` +
52
+ `Synthesize these takeaways into a comprehensive research report.`;
53
+ try {
54
+ const structuredModel = chatModel.withStructuredOutput(SynthesisOutputSchema, {
55
+ method: "jsonSchema",
56
+ name: "research_synthesis",
57
+ });
58
+ const result = await structuredModel.invoke([
59
+ new SystemMessage(SYSTEM_PROMPT),
60
+ new HumanMessage(humanMsg),
61
+ ]);
62
+ logInfo("Synthesis complete", {
63
+ node: "synthesizer",
64
+ researchId: subject,
65
+ summaryLength: result.synthesizedSummary.length,
66
+ keyFindingsCount: result.keyFindings.length,
67
+ limitationsCount: result.limitations?.length ?? 0,
68
+ });
69
+ return {
70
+ synthesizedSummary: result.synthesizedSummary.trim(),
71
+ keyFindings: result.keyFindings.map((f) => f.trim()),
72
+ limitations: (result.limitations ?? []).map((l) => l.trim()),
73
+ };
74
+ }
75
+ catch (err) {
76
+ logError("Synthesis failed, returning fallback", {
77
+ node: "synthesizer",
78
+ researchId: subject,
79
+ errorCode: ErrorCodes.SUMMARIZATION_FAILED,
80
+ error: err instanceof Error ? err.message : String(err),
81
+ });
82
+ // Synthesis failure is non-fatal — caller falls back to composite summary
83
+ throw err;
84
+ }
85
+ }
86
+ //# sourceMappingURL=synthesizer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"synthesizer.js","sourceRoot":"","sources":["../../../src/app/summarization/synthesizer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ import { z } from "zod/v4";
2
+ declare const envSchema: z.ZodObject<{
3
+ NODE_ENV: z.ZodDefault<z.ZodEnum<{
4
+ development: "development";
5
+ test: "test";
6
+ production: "production";
7
+ }>>;
8
+ LOG_LEVEL: z.ZodDefault<z.ZodEnum<{
9
+ error: "error";
10
+ info: "info";
11
+ warn: "warn";
12
+ debug: "debug";
13
+ }>>;
14
+ QDRANT_URL: z.ZodDefault<z.ZodURL>;
15
+ QDRANT_API_KEY: z.ZodOptional<z.ZodString>;
16
+ QDRANT_TIMEOUT_MS: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
17
+ OLLAMA_HOST: z.ZodDefault<z.ZodURL>;
18
+ OLLAMA_EMBEDDING_MODEL: z.ZodDefault<z.ZodString>;
19
+ OLLAMA_CHAT_MODEL: z.ZodDefault<z.ZodString>;
20
+ RMS_OLLAMA_EMBEDDING_MODEL: z.ZodOptional<z.ZodString>;
21
+ RMS_OLLAMA_CHAT_MODEL: z.ZodOptional<z.ZodString>;
22
+ RMS_OLLAMA_NUM_CTX: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
23
+ SEARXNG_API_BASE: z.ZodDefault<z.ZodURL>;
24
+ SEARXNG_ENGINES: z.ZodOptional<z.ZodString>;
25
+ SEARXNG_LANGUAGE: z.ZodOptional<z.ZodString>;
26
+ SEARXNG_TIME_RANGE: z.ZodOptional<z.ZodString>;
27
+ SEARXNG_URL_BLOCKLIST: z.ZodOptional<z.ZodString>;
28
+ RMS_FRESHNESS_DAYS: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
29
+ LANGCHAIN_TRACING_V2: z.ZodDefault<z.ZodCodec<z.ZodString, z.ZodBoolean>>;
30
+ LANGCHAIN_API_KEY: z.ZodOptional<z.ZodString>;
31
+ RMS_MCP_AUTH_TOKEN: z.ZodOptional<z.ZodString>;
32
+ RMS_USER_AGENT: z.ZodOptional<z.ZodString>;
33
+ RMS_CHECKPOINTER: z.ZodDefault<z.ZodEnum<{
34
+ memory: "memory";
35
+ sqlite: "sqlite";
36
+ }>>;
37
+ RMS_CHECKPOINT_DB: z.ZodDefault<z.ZodString>;
38
+ }, z.core.$strip>;
39
+ export type Env = z.infer<typeof envSchema>;
40
+ /** Reset cached env (for tests only) */
41
+ export declare function resetEnv(): void;
42
+ /**
43
+ * Loads and validates environment variables (cached after first call).
44
+ * @note In tests, call `resetEnv()` before each test to avoid stale cached values
45
+ * from bleeding into subsequent test cases.
46
+ */
47
+ export declare function loadEnv(): Env;
48
+ export {};
49
+ //# sourceMappingURL=env.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../src/config/env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AAE3B,QAAA,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAgCb,CAAC;AAEH,MAAM,MAAM,GAAG,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,CAAC;AAI5C,wCAAwC;AACxC,wBAAgB,QAAQ,IAAI,IAAI,CAE/B;AAED;;;;GAIG;AACH,wBAAgB,OAAO,IAAI,GAAG,CAW7B"}
@@ -0,0 +1,54 @@
1
+ import { z } from "zod/v4";
2
+ const envSchema = z.object({
3
+ NODE_ENV: z.enum(["development", "test", "production"]).default("development"),
4
+ LOG_LEVEL: z.enum(["debug", "info", "warn", "error"]).default("info"),
5
+ QDRANT_URL: z.url().default("http://localhost:6333"),
6
+ QDRANT_API_KEY: z.string().optional(),
7
+ QDRANT_TIMEOUT_MS: z.coerce.number().int().positive().default(10000),
8
+ OLLAMA_HOST: z.url().default("http://localhost:11434"),
9
+ OLLAMA_EMBEDDING_MODEL: z.string().default("bge-m3"),
10
+ OLLAMA_CHAT_MODEL: z.string().default("qwen3:8b"),
11
+ RMS_OLLAMA_EMBEDDING_MODEL: z.string().optional(),
12
+ RMS_OLLAMA_CHAT_MODEL: z.string().optional(),
13
+ RMS_OLLAMA_NUM_CTX: z.coerce.number().int().positive().default(16384),
14
+ SEARXNG_API_BASE: z.url().default("http://localhost:8080"),
15
+ SEARXNG_ENGINES: z.string().optional(),
16
+ SEARXNG_LANGUAGE: z.string().optional(),
17
+ SEARXNG_TIME_RANGE: z.string().optional(),
18
+ /** Comma-separated list of additional domains to block from search results. */
19
+ SEARXNG_URL_BLOCKLIST: z.string().optional(),
20
+ RMS_FRESHNESS_DAYS: z.coerce.number().int().positive().default(7),
21
+ /** Zod v4 codec: coerces env string "true"/"false" → boolean. */
22
+ LANGCHAIN_TRACING_V2: z.stringbool().default(false),
23
+ LANGCHAIN_API_KEY: z.string().optional(),
24
+ RMS_MCP_AUTH_TOKEN: z.string().optional(),
25
+ RMS_USER_AGENT: z.string().optional(),
26
+ /** Checkpointer backend: "memory" (default, dev only) or "sqlite" (durable, for HITL). */
27
+ RMS_CHECKPOINTER: z.enum(["memory", "sqlite"]).default("memory"),
28
+ /** SQLite file path for the checkpoint database (when RMS_CHECKPOINTER=sqlite). */
29
+ RMS_CHECKPOINT_DB: z.string().default("rms_checkpoints.db"),
30
+ });
31
+ let _env = null;
32
+ /** Reset cached env (for tests only) */
33
+ export function resetEnv() {
34
+ _env = null;
35
+ }
36
+ /**
37
+ * Loads and validates environment variables (cached after first call).
38
+ * @note In tests, call `resetEnv()` before each test to avoid stale cached values
39
+ * from bleeding into subsequent test cases.
40
+ */
41
+ export function loadEnv() {
42
+ if (_env)
43
+ return _env;
44
+ const parsed = envSchema.safeParse(process.env);
45
+ if (!parsed.success) {
46
+ const msg = parsed.error.issues
47
+ .map((e) => `${e.path.map(String).join(".")}: ${e.message}`)
48
+ .join("; ");
49
+ throw new Error(`Invalid environment configuration: ${msg}`);
50
+ }
51
+ _env = parsed.data;
52
+ return _env;
53
+ }
54
+ //# sourceMappingURL=env.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/config/env.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ import { z } from "zod/v4";
2
+ /** Research entry status in the lifecycle */
3
+ export declare const ResearchStatusSchema: z.ZodEnum<{
4
+ active: "active";
5
+ stale: "stale";
6
+ refreshing: "refreshing";
7
+ archived: "archived";
8
+ low_confidence: "low_confidence";
9
+ }>;
10
+ export type ResearchStatus = z.infer<typeof ResearchStatusSchema>;
11
+ /** Response contract version stamped on all RMS tool outputs. */
12
+ export declare const RESPONSE_CONTRACT_VERSION = "1.0";
13
+ /** Per-source summary stored in a Research entry. */
14
+ export declare const SourceSummarySchema: z.ZodObject<{
15
+ url: z.ZodString;
16
+ title: z.ZodString;
17
+ keyTakeaways: z.ZodString;
18
+ relevance: z.ZodDefault<z.ZodNumber>;
19
+ tags: z.ZodDefault<z.ZodArray<z.ZodString>>;
20
+ language: z.ZodDefault<z.ZodString>;
21
+ }, z.core.$strip>;
22
+ export type SourceSummaryEntry = z.infer<typeof SourceSummarySchema>;
23
+ /** Research entry — the core domain object for RMS. */
24
+ export declare const ResearchSchema: z.ZodObject<{
25
+ id: z.ZodUUID;
26
+ subject: z.ZodString;
27
+ summary: z.ZodString;
28
+ sourceSummaries: z.ZodDefault<z.ZodArray<z.ZodObject<{
29
+ url: z.ZodString;
30
+ title: z.ZodString;
31
+ keyTakeaways: z.ZodString;
32
+ relevance: z.ZodDefault<z.ZodNumber>;
33
+ tags: z.ZodDefault<z.ZodArray<z.ZodString>>;
34
+ language: z.ZodDefault<z.ZodString>;
35
+ }, z.core.$strip>>>;
36
+ sourceUrls: z.ZodDefault<z.ZodArray<z.ZodString>>;
37
+ searchQueries: z.ZodDefault<z.ZodArray<z.ZodString>>;
38
+ createdAt: z.ZodOptional<z.ZodISODateTime>;
39
+ updatedAt: z.ZodOptional<z.ZodISODateTime>;
40
+ expiresAt: z.ZodOptional<z.ZodISODateTime>;
41
+ status: z.ZodDefault<z.ZodEnum<{
42
+ active: "active";
43
+ stale: "stale";
44
+ refreshing: "refreshing";
45
+ archived: "archived";
46
+ low_confidence: "low_confidence";
47
+ }>>;
48
+ confidenceScore: z.ZodDefault<z.ZodNumber>;
49
+ sourceCount: z.ZodDefault<z.ZodNumber>;
50
+ tenantId: z.ZodOptional<z.ZodString>;
51
+ tags: z.ZodDefault<z.ZodArray<z.ZodString>>;
52
+ language: z.ZodDefault<z.ZodString>;
53
+ rawResultCount: z.ZodDefault<z.ZodNumber>;
54
+ keyFindings: z.ZodOptional<z.ZodArray<z.ZodString>>;
55
+ limitations: z.ZodOptional<z.ZodArray<z.ZodString>>;
56
+ metadata: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
57
+ }, z.core.$strip>;
58
+ export type Research = z.infer<typeof ResearchSchema>;
59
+ //# sourceMappingURL=contracts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../../src/domain/contracts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AAE3B,6CAA6C;AAC7C,eAAO,MAAM,oBAAoB;;;;;;EAM/B,CAAC;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAElE,iEAAiE;AACjE,eAAO,MAAM,yBAAyB,QAAQ,CAAC;AAE/C,qDAAqD;AACrD,eAAO,MAAM,mBAAmB;;;;;;;iBAO9B,CAAC;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAErE,uDAAuD;AACvD,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA6BzB,CAAC;AACH,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC"}
@@ -0,0 +1,52 @@
1
+ import { z } from "zod/v4";
2
+ /** Research entry status in the lifecycle */
3
+ export const ResearchStatusSchema = z.enum([
4
+ "active",
5
+ "stale",
6
+ "refreshing",
7
+ "archived",
8
+ "low_confidence",
9
+ ]);
10
+ /** Response contract version stamped on all RMS tool outputs. */
11
+ export const RESPONSE_CONTRACT_VERSION = "1.0";
12
+ /** Per-source summary stored in a Research entry. */
13
+ export const SourceSummarySchema = z.object({
14
+ url: z.string(),
15
+ title: z.string(),
16
+ keyTakeaways: z.string(),
17
+ relevance: z.number().min(0).max(1).default(0.5),
18
+ tags: z.array(z.string()).default([]),
19
+ language: z.string().default("en"),
20
+ });
21
+ /** Research entry — the core domain object for RMS. */
22
+ export const ResearchSchema = z.object({
23
+ id: z.uuid(),
24
+ subject: z.string().min(1),
25
+ summary: z.string().min(1),
26
+ sourceSummaries: z.array(SourceSummarySchema).default([]),
27
+ sourceUrls: z.array(z.string()).default([]),
28
+ searchQueries: z.array(z.string()).default([]),
29
+ /**
30
+ * Timestamps use ISO 8601 with timezone offset.
31
+ *
32
+ * Design note: These intentionally allow future dates:
33
+ * - `expiresAt` is always in the future (freshness window)
34
+ * - `createdAt` / `updatedAt` are system-generated, not user input
35
+ * - Adding `max: now()` would break deserialization under clock skew
36
+ * or when reading entries created on a different host
37
+ */
38
+ createdAt: z.iso.datetime({ offset: true }).optional(),
39
+ updatedAt: z.iso.datetime({ offset: true }).optional(),
40
+ expiresAt: z.iso.datetime({ offset: true }).optional(),
41
+ status: ResearchStatusSchema.default("active"),
42
+ confidenceScore: z.number().min(0).max(1).default(0.5),
43
+ sourceCount: z.number().int().min(0).default(0),
44
+ tenantId: z.string().optional(),
45
+ tags: z.array(z.string()).default([]),
46
+ language: z.string().default("en"),
47
+ rawResultCount: z.number().int().min(0).default(0),
48
+ keyFindings: z.array(z.string()).optional(),
49
+ limitations: z.array(z.string()).optional(),
50
+ metadata: z.record(z.string(), z.unknown()).default({}),
51
+ });
52
+ //# sourceMappingURL=contracts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contracts.js","sourceRoot":"","sources":["../../src/domain/contracts.ts"],"names":[],"mappings":"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"}