@deepcitation/deepcitation-js 1.1.27 → 1.1.28

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 (79) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +253 -253
  3. package/lib/chunk-2IZXUOQR.js +66 -0
  4. package/lib/chunk-4FGOHQFP.cjs +66 -0
  5. package/lib/chunk-CFXDRAJL.cjs +1 -0
  6. package/lib/chunk-DEUSSEFH.js +2 -0
  7. package/lib/chunk-F2MMVEVC.cjs +1 -0
  8. package/lib/chunk-J7U6YFOI.cjs +2 -0
  9. package/lib/chunk-O2XFH626.js +1 -0
  10. package/lib/chunk-RQPZSRID.js +1 -0
  11. package/lib/client/index.cjs +1 -0
  12. package/lib/client/{DeepCitation.d.ts → index.d.cts} +159 -3
  13. package/lib/client/index.d.ts +342 -2
  14. package/lib/client/index.js +1 -1
  15. package/lib/index.cjs +1 -0
  16. package/lib/index.d.cts +127 -0
  17. package/lib/index.d.ts +126 -22
  18. package/lib/index.js +1 -20
  19. package/lib/prompts/index.cjs +1 -0
  20. package/lib/prompts/index.d.cts +196 -0
  21. package/lib/prompts/index.d.ts +196 -3
  22. package/lib/prompts/index.js +1 -3
  23. package/lib/react/index.cjs +4 -0
  24. package/lib/react/index.js +4 -20
  25. package/lib/types/index.cjs +1 -0
  26. package/lib/types/index.d.cts +96 -0
  27. package/lib/types/index.d.ts +96 -11
  28. package/lib/types/index.js +1 -7
  29. package/package.json +46 -11
  30. package/lib/client/DeepCitation.js +0 -374
  31. package/lib/client/types.d.ts +0 -154
  32. package/lib/client/types.js +0 -1
  33. package/lib/parsing/normalizeCitation.d.ts +0 -5
  34. package/lib/parsing/normalizeCitation.js +0 -198
  35. package/lib/parsing/parseCitation.d.ts +0 -79
  36. package/lib/parsing/parseCitation.js +0 -431
  37. package/lib/parsing/parseWorkAround.d.ts +0 -2
  38. package/lib/parsing/parseWorkAround.js +0 -73
  39. package/lib/prompts/citationPrompts.d.ts +0 -138
  40. package/lib/prompts/citationPrompts.js +0 -168
  41. package/lib/prompts/promptCompression.d.ts +0 -14
  42. package/lib/prompts/promptCompression.js +0 -127
  43. package/lib/prompts/types.d.ts +0 -4
  44. package/lib/prompts/types.js +0 -1
  45. package/lib/react/CitationComponent.d.ts +0 -106
  46. package/lib/react/CitationComponent.js +0 -419
  47. package/lib/react/CitationVariants.d.ts +0 -132
  48. package/lib/react/CitationVariants.js +0 -277
  49. package/lib/react/DiffDisplay.d.ts +0 -10
  50. package/lib/react/DiffDisplay.js +0 -33
  51. package/lib/react/Popover.d.ts +0 -15
  52. package/lib/react/Popover.js +0 -20
  53. package/lib/react/UrlCitationComponent.d.ts +0 -83
  54. package/lib/react/UrlCitationComponent.js +0 -224
  55. package/lib/react/VerificationTabs.d.ts +0 -10
  56. package/lib/react/VerificationTabs.js +0 -36
  57. package/lib/react/icons.d.ts +0 -22
  58. package/lib/react/icons.js +0 -16
  59. package/lib/react/index.d.ts +0 -17
  60. package/lib/react/primitives.d.ts +0 -99
  61. package/lib/react/primitives.js +0 -187
  62. package/lib/react/types.d.ts +0 -315
  63. package/lib/react/types.js +0 -1
  64. package/lib/react/useSmartDiff.d.ts +0 -16
  65. package/lib/react/useSmartDiff.js +0 -64
  66. package/lib/react/utils.d.ts +0 -44
  67. package/lib/react/utils.js +0 -88
  68. package/lib/types/boxes.d.ts +0 -11
  69. package/lib/types/boxes.js +0 -1
  70. package/lib/types/citation.d.ts +0 -39
  71. package/lib/types/citation.js +0 -1
  72. package/lib/types/search.d.ts +0 -19
  73. package/lib/types/search.js +0 -1
  74. package/lib/types/verification.d.ts +0 -27
  75. package/lib/types/verification.js +0 -11
  76. package/lib/utils/diff.d.ts +0 -60
  77. package/lib/utils/diff.js +0 -414
  78. package/lib/utils/sha.d.ts +0 -10
  79. package/lib/utils/sha.js +0 -108
@@ -1,374 +0,0 @@
1
- import { getAllCitationsFromLlmOutput } from "../parsing/parseCitation.js";
2
- import { generateCitationKey } from "../react/utils.js";
3
- const DEFAULT_API_URL = "https://api.deepcitation.com";
4
- /** Convert File/Blob/Buffer to a Blob suitable for FormData */
5
- function toBlob(file, filename) {
6
- if (typeof Buffer !== "undefined" && Buffer.isBuffer(file)) {
7
- const uint8 = Uint8Array.from(file);
8
- return { blob: new Blob([uint8]), name: filename || "document" };
9
- }
10
- if (file instanceof Blob) {
11
- return {
12
- blob: file,
13
- name: filename || (file instanceof File ? file.name : "document"),
14
- };
15
- }
16
- throw new Error("Invalid file type. Expected File, Blob, or Buffer.");
17
- }
18
- /** Extract error message from API response */
19
- async function extractErrorMessage(response, fallbackAction) {
20
- const error = await response.json().catch(() => ({}));
21
- return (error?.error?.message ||
22
- `${fallbackAction} failed with status ${response.status}`);
23
- }
24
- /**
25
- * DeepCitation client for file upload and citation verification.
26
- *
27
- * @example
28
- * ```typescript
29
- * import { DeepCitation } from '@deepcitation/deepcitation-js';
30
- *
31
- * const dc = new DeepCitation({ apiKey: process.env.DEEPCITATION_API_KEY });
32
- *
33
- * // Upload a file
34
- * const { attachmentId, promptContent } = await dc.uploadFile(file);
35
- *
36
- * // Include promptContent in your LLM messages
37
- * const response = await llm.chat({
38
- * messages: [
39
- * { role: "system", content: wrapSystemCitationPrompt({ systemPrompt }) },
40
- * { role: "user", content: userMessage + "\n\n" + promptContent },
41
- * ]
42
- * });
43
- *
44
- * // Verify citations in the LLM output
45
- * const citations = getAllCitationsFromLlmOutput(response);
46
- * const verified = await dc.verifyCitations(attachmentId, citations);
47
- * ```
48
- */
49
- export class DeepCitation {
50
- apiKey;
51
- apiUrl;
52
- /**
53
- * Create a new DeepCitation client instance.
54
- *
55
- * @param config - Configuration options
56
- * @throws Error if apiKey is not provided
57
- */
58
- constructor(config) {
59
- if (!config.apiKey) {
60
- throw new Error("DeepCitation API key is required. Get one at https://deepcitation.com/dashboard");
61
- }
62
- this.apiKey = config.apiKey;
63
- this.apiUrl = config.apiUrl?.replace(/\/$/, "") || DEFAULT_API_URL;
64
- }
65
- /**
66
- * Upload a file for citation verification.
67
- *
68
- * Supported file types:
69
- * - PDF documents
70
- * - Images (PNG, JPEG, WebP, AVIF, HEIC)
71
- * - Coming soon: DOCX, XLSX, plain text
72
- *
73
- * @param file - The file to upload (File, Blob, or Buffer)
74
- * @param options - Optional upload options
75
- * @returns Upload response with attachmentId and extracted text
76
- *
77
- * @example
78
- * ```typescript
79
- * // Browser with File object
80
- * const file = document.querySelector('input[type="file"]').files[0];
81
- * const result = await dc.uploadFile(file);
82
- *
83
- * // Node.js with Buffer
84
- * const buffer = fs.readFileSync('document.pdf');
85
- * const result = await dc.uploadFile(buffer, { filename: 'document.pdf' });
86
- * ```
87
- */
88
- async uploadFile(file, options) {
89
- const { blob, name } = toBlob(file, options?.filename);
90
- const formData = new FormData();
91
- formData.append("file", blob, name);
92
- if (options?.attachmentId)
93
- formData.append("attachmentId", options.attachmentId);
94
- if (options?.filename)
95
- formData.append("filename", options.filename);
96
- const response = await fetch(`${this.apiUrl}/prepareFile`, {
97
- method: "POST",
98
- headers: { Authorization: `Bearer ${this.apiKey}` },
99
- body: formData,
100
- });
101
- if (!response.ok) {
102
- throw new Error(await extractErrorMessage(response, "Upload"));
103
- }
104
- return (await response.json());
105
- }
106
- /**
107
- * Convert a URL or Office file to PDF for citation verification.
108
- * The converted file can then be processed with prepareConvertedFile().
109
- *
110
- * Supported Office formats:
111
- * - Microsoft Word (.doc, .docx)
112
- * - Microsoft Excel (.xls, .xlsx)
113
- * - Microsoft PowerPoint (.ppt, .pptx)
114
- * - OpenDocument (.odt, .ods, .odp)
115
- * - Rich Text Format (.rtf)
116
- * - CSV (.csv)
117
- *
118
- * @param input - URL string or object with URL/file options
119
- * @returns Conversion result with attachmentId for prepareConvertedFile
120
- *
121
- * @example
122
- * ```typescript
123
- * // Convert a URL to PDF
124
- * const result = await dc.convertToPdf({ url: "https://example.com/article" });
125
- *
126
- * // Convert an Office document
127
- * const result = await dc.convertToPdf({
128
- * file: docxBuffer,
129
- * filename: "report.docx"
130
- * });
131
- *
132
- * // Then prepare the file for verification
133
- * const { deepTextPromptPortion, attachmentId } = await dc.prepareConvertedFile({
134
- * attachmentId: result.attachmentId
135
- * });
136
- * ```
137
- */
138
- async convertToPdf(input) {
139
- const inputObj = typeof input === "string" ? { url: input } : input;
140
- const { url, file, filename, attachmentId } = inputObj;
141
- if (!url && !file) {
142
- throw new Error("Either url or file must be provided");
143
- }
144
- let response;
145
- if (url) {
146
- response = await fetch(`${this.apiUrl}/convertFile`, {
147
- method: "POST",
148
- headers: {
149
- Authorization: `Bearer ${this.apiKey}`,
150
- "Content-Type": "application/json",
151
- },
152
- body: JSON.stringify({ url, filename, attachmentId }),
153
- });
154
- }
155
- else {
156
- const { blob, name } = toBlob(file, filename);
157
- const formData = new FormData();
158
- formData.append("file", blob, name);
159
- if (attachmentId)
160
- formData.append("attachmentId", attachmentId);
161
- if (filename)
162
- formData.append("filename", filename);
163
- response = await fetch(`${this.apiUrl}/convertFile`, {
164
- method: "POST",
165
- headers: { Authorization: `Bearer ${this.apiKey}` },
166
- body: formData,
167
- });
168
- }
169
- if (!response.ok) {
170
- throw new Error(await extractErrorMessage(response, "Conversion"));
171
- }
172
- return (await response.json());
173
- }
174
- /**
175
- * Prepare a previously converted file for citation verification.
176
- * Use this after calling convertToPdf() to extract text and get deepTextPromptPortion.
177
- *
178
- * @param options - Options with attachmentId from convertFile
179
- * @returns Upload response with attachmentId and extracted text
180
- *
181
- * @example
182
- * ```typescript
183
- * // First convert the file
184
- * const converted = await dc.convertToPdf({ url: "https://example.com/article" });
185
- *
186
- * // Then prepare it for verification
187
- * const { deepTextPromptPortion, attachmentId } = await dc.prepareConvertedFile({
188
- * attachmentId: converted.attachmentId
189
- * });
190
- *
191
- * // Use deepTextPromptPortion in your LLM prompt...
192
- * ```
193
- */
194
- async prepareConvertedFile(options) {
195
- const response = await fetch(`${this.apiUrl}/prepareFile`, {
196
- method: "POST",
197
- headers: {
198
- Authorization: `Bearer ${this.apiKey}`,
199
- "Content-Type": "application/json",
200
- },
201
- body: JSON.stringify({
202
- attachmentId: options.attachmentId,
203
- }),
204
- });
205
- if (!response.ok) {
206
- throw new Error(await extractErrorMessage(response, "Prepare"));
207
- }
208
- return (await response.json());
209
- }
210
- /**
211
- * Upload multiple files for citation verification and get structured content.
212
- * This is the recommended way to prepare files for LLM prompts.
213
- *
214
- * @param files - Array of files to upload with optional filenames and attachmentIds
215
- * @returns Object containing fileDataParts for verification and deepTextPromptPortion for LLM
216
- *
217
- * @example
218
- * ```typescript
219
- * const { fileDataParts, deepTextPromptPortion } = await dc.prepareFiles([
220
- * { file: pdfBuffer, filename: "report.pdf" },
221
- * { file: invoiceBuffer, filename: "invoice.pdf" },
222
- * ]);
223
- *
224
- * // Use deepTextPromptPortion in wrapCitationPrompt
225
- * const { enhancedSystemPrompt, enhancedUserPrompt } = wrapCitationPrompt({
226
- * systemPrompt,
227
- * userPrompt,
228
- * deepTextPromptPortion
229
- * });
230
- *
231
- * // Use fileDataParts later for verification
232
- * const result = await dc.verifyCitationsFromLlmOutput({ llmOutput, fileDataParts });
233
- * ```
234
- */
235
- async prepareFiles(files) {
236
- if (files.length === 0) {
237
- return { fileDataParts: [], deepTextPromptPortion: [] };
238
- }
239
- // Upload all files in parallel
240
- const uploadPromises = files.map(({ file, filename, attachmentId }) => this.uploadFile(file, { filename, attachmentId }).then((result) => ({
241
- result,
242
- filename,
243
- })));
244
- const uploadResults = await Promise.all(uploadPromises);
245
- // Extract file data parts with deepTextPromptPortion included (single source of truth)
246
- const fileDataParts = uploadResults.map(({ result, filename }) => ({
247
- attachmentId: result.attachmentId,
248
- deepTextPromptPortion: result.deepTextPromptPortion,
249
- filename: filename || result.metadata?.filename,
250
- }));
251
- // Also return separate array for backwards compatibility (deprecated)
252
- const deepTextPromptPortion = fileDataParts.map((part) => part.deepTextPromptPortion);
253
- return { fileDataParts, deepTextPromptPortion };
254
- }
255
- /**
256
- * Verify citations against a previously uploaded file.
257
- *
258
- * @param attachmentId - The attachment ID returned from uploadFile
259
- * @param citations - Citations to verify (from getAllCitationsFromLlmOutput)
260
- * @param options - Optional verification options
261
- * @returns Verification results with status and proof images
262
- *
263
- * @example
264
- * ```typescript
265
- * import { getAllCitationsFromLlmOutput } from '@deepcitation/deepcitation-js';
266
- *
267
- * const citations = getAllCitationsFromLlmOutput(llmResponse);
268
- * const verified = await dc.verifyCitations(attachmentId, citations);
269
- *
270
- * for (const [key, result] of Object.entries(verified.verifications)) {
271
- * console.log(key, result.searchState?.status);
272
- * // "found", "partial_text_found", "not_found", etc.
273
- * }
274
- * ```
275
- */
276
- async verifyCitations(attachmentId, citations, options) {
277
- // Normalize citations to a map with citation keys
278
- const citationMap = {};
279
- if (Array.isArray(citations)) {
280
- // Array of citations - generate keys
281
- for (const citation of citations) {
282
- const key = generateCitationKey(citation);
283
- citationMap[key] = citation;
284
- }
285
- }
286
- else if (typeof citations === "object" && citations !== null) {
287
- // Check if it's a single citation or a map
288
- if ("fullPhrase" in citations || "value" in citations) {
289
- // Single citation
290
- const key = generateCitationKey(citations);
291
- citationMap[key] = citations;
292
- }
293
- else {
294
- // Already a map
295
- Object.assign(citationMap, citations);
296
- }
297
- }
298
- else {
299
- throw new Error("Invalid citations format");
300
- }
301
- const requestUrl = `${this.apiUrl}/verifyCitations`;
302
- const requestBody = {
303
- data: {
304
- attachmentId,
305
- citations: citationMap,
306
- outputImageFormat: options?.outputImageFormat || "avif",
307
- },
308
- };
309
- const response = await fetch(requestUrl, {
310
- method: "POST",
311
- headers: {
312
- Authorization: `Bearer ${this.apiKey}`,
313
- "Content-Type": "application/json",
314
- },
315
- body: JSON.stringify(requestBody),
316
- });
317
- if (!response.ok) {
318
- throw new Error(await extractErrorMessage(response, "Verification"));
319
- }
320
- const result = (await response.json());
321
- return result;
322
- }
323
- /**
324
- * Verify citations from LLM output with automatic parsing.
325
- * This is the recommended way to verify citations for new integrations.
326
- *
327
- * @param input - Object containing llmOutput and optional fileDataParts
328
- * @returns Verification results with status and proof images
329
- *
330
- * @example
331
- * ```typescript
332
- * const result = await dc.verifyCitationsFromLlmOutput({
333
- * llmOutput: response.content,
334
- * fileDataParts, // From prepareFiles()
335
- * });
336
- *
337
- * for (const [key, result] of Object.entries(result.verifications)) {
338
- * console.log(key, result.searchState?.status);
339
- * }
340
- * ```
341
- */
342
- async verifyCitationsFromLlmOutput(input, citations) {
343
- const { llmOutput, outputImageFormat = "avif" } = input;
344
- // Parse citations from LLM output
345
- if (!citations)
346
- citations = getAllCitationsFromLlmOutput(llmOutput);
347
- // If no citations found, return empty result
348
- if (Object.keys(citations).length === 0) {
349
- return { verifications: {} };
350
- }
351
- // Group citations by attachmentId
352
- const citationsByAttachment = new Map();
353
- for (const [key, citation] of Object.entries(citations)) {
354
- const attachmentId = citation.attachmentId || "";
355
- if (!citationsByAttachment.has(attachmentId)) {
356
- citationsByAttachment.set(attachmentId, {});
357
- }
358
- citationsByAttachment.get(attachmentId)[key] = citation;
359
- }
360
- // Verify all files in parallel
361
- const verificationPromises = [];
362
- for (const [attachmentId, fileCitations] of citationsByAttachment) {
363
- if (attachmentId) {
364
- verificationPromises.push(this.verifyCitations(attachmentId, fileCitations, { outputImageFormat }));
365
- }
366
- }
367
- const results = await Promise.all(verificationPromises);
368
- const allHighlights = {};
369
- for (const result of results) {
370
- Object.assign(allHighlights, result.verifications);
371
- }
372
- return { verifications: allHighlights };
373
- }
374
- }
@@ -1,154 +0,0 @@
1
- import type { Citation, Verification } from "../types/index.js";
2
- /**
3
- * Configuration options for the DeepCitation client
4
- */
5
- export interface DeepCitationConfig {
6
- /** Your DeepCitation API key (starts with sk-dc-) */
7
- apiKey: string;
8
- /** Optional custom API base URL. Defaults to https://api.deepcitation.com */
9
- apiUrl?: string;
10
- }
11
- /**
12
- * Response from uploading a file for citation verification
13
- */
14
- export interface UploadFileResponse {
15
- /** The attachment ID assigned by DeepCitation (custom or auto-generated) */
16
- attachmentId: string;
17
- /** The full text content formatted for LLM prompts with page markers and line IDs. Use this in your user prompts. */
18
- deepTextPromptPortion: string;
19
- /** Form fields extracted from PDF forms */
20
- formFields?: Array<{
21
- name: string;
22
- value?: string;
23
- pageIndex?: number;
24
- type?: string;
25
- }>;
26
- /** Metadata about the processed file */
27
- metadata: {
28
- filename: string;
29
- mimeType: string;
30
- pageCount: number;
31
- textByteSize: number;
32
- };
33
- /** Processing status */
34
- status: "ready" | "error";
35
- /** Time taken to process the file in milliseconds */
36
- processingTimeMs?: number;
37
- /** Error message if status is "error" */
38
- error?: string;
39
- }
40
- /**
41
- * Options for file upload
42
- */
43
- export interface UploadFileOptions {
44
- /** Optional custom attachment ID to use instead of auto-generated one */
45
- attachmentId?: string;
46
- /** Optional custom filename (uses File.name if not provided) */
47
- filename?: string;
48
- }
49
- /**
50
- * Response from verifying citations
51
- */
52
- export interface VerifyCitationsResponse {
53
- /** Map of citation keys to their verification results */
54
- verifications: Record<string, Verification>;
55
- }
56
- /**
57
- * Options for citation verification
58
- */
59
- export interface VerifyCitationsOptions {
60
- /** Output image format for verification screenshots */
61
- outputImageFormat?: "jpeg" | "png" | "avif";
62
- }
63
- /**
64
- * Simplified citation input for verification
65
- */
66
- export type CitationInput = Citation | Record<string, Citation>;
67
- /**
68
- * Input for file upload in prepareFiles
69
- */
70
- export interface FileInput {
71
- /** The file content (File, Blob, or Buffer) */
72
- file: File | Blob | Buffer;
73
- /** Optional filename */
74
- filename?: string;
75
- /** Optional custom attachment ID */
76
- attachmentId?: string;
77
- }
78
- /**
79
- * File reference returned from prepareFiles
80
- */
81
- export interface FileDataPart {
82
- /** The attachment ID assigned by DeepCitation */
83
- attachmentId: string;
84
- /** The formatted text content for LLM prompts (with page markers and line IDs) */
85
- deepTextPromptPortion: string;
86
- /** Optional filename for display purposes */
87
- filename?: string;
88
- }
89
- /**
90
- * Result from prepareFiles
91
- */
92
- export interface PrepareFilesResult {
93
- /** Array of file references for verification (includes deepTextPromptPortion for each file) */
94
- fileDataParts: FileDataPart[];
95
- /**
96
- * Array of formatted text content for LLM prompts (with page markers and line IDs).
97
- * @deprecated Use fileDataParts[].deepTextPromptPortion instead for single source of truth.
98
- * This is kept for backwards compatibility but will be removed in a future version.
99
- */
100
- deepTextPromptPortion: string[];
101
- }
102
- /**
103
- * Input for verifyCitationsFromLlmOutput
104
- */
105
- export interface VerifyCitationsFromLlmOutput {
106
- /** The LLM response containing citations */
107
- llmOutput: string;
108
- /** Optional file references (required for Zero Data Retention or after storage expires) */
109
- fileDataParts?: FileDataPart[];
110
- /** Output image format for verification screenshots */
111
- outputImageFormat?: "jpeg" | "png" | "avif";
112
- }
113
- /**
114
- * Input for convertFile - convert URL or Office file to PDF
115
- */
116
- export interface ConvertFileInput {
117
- /** URL to convert to PDF (for web pages or direct PDF links) */
118
- url?: string;
119
- /** Office file to convert (doc, docx, xls, xlsx, ppt, pptx, odt, ods, odp) */
120
- file?: File | Blob | Buffer;
121
- /** Optional custom filename for the converted PDF */
122
- filename?: string;
123
- /** Optional custom attachment ID */
124
- attachmentId?: string;
125
- }
126
- /**
127
- * Response from convertFile
128
- */
129
- export interface ConvertFileResponse {
130
- /** The attachment ID assigned by DeepCitation. Pass this to prepareConvertedFile(). */
131
- attachmentId: string;
132
- /** Metadata about the conversion */
133
- metadata: {
134
- /** Original filename before conversion */
135
- originalFilename: string;
136
- /** Original MIME type before conversion */
137
- originalMimeType: string;
138
- /** MIME type after conversion (always application/pdf) */
139
- convertedMimeType: string;
140
- /** Time taken for conversion in milliseconds */
141
- conversionTimeMs: number;
142
- };
143
- /** Conversion status */
144
- status: "converted" | "error";
145
- /** Error message if status is "error" */
146
- error?: string;
147
- }
148
- /**
149
- * Options for processing a converted file
150
- */
151
- export interface PrepareConvertedFileOptions {
152
- /** The attachment ID from a previous convertFile call */
153
- attachmentId: string;
154
- }
@@ -1 +0,0 @@
1
- export {};
@@ -1,5 +0,0 @@
1
- export declare const removeCitations: (pageText: string, leaveKeySpanBehind?: boolean) => string;
2
- export declare const removePageNumberMetadata: (pageText: string) => string;
3
- export declare const removeLineIdMetadata: (pageText: string) => string;
4
- export declare const getCitationPageNumber: (startPageKey?: string | null) => number | null;
5
- export declare const normalizeCitations: (response: string) => string;