@deepcitation/deepcitation-js 1.0.6 → 1.0.8

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.
@@ -1,5 +1,5 @@
1
- import type { Citation } from "../types/index";
2
- import type { CitationInput, ConvertFileInput, ConvertFileResponse, DeepCitationConfig, FileInput, PrepareConvertedFileOptions, PrepareFilesResult, UploadFileOptions, UploadFileResponse, VerifyCitationsFromLlmOutput, VerifyCitationsOptions, VerifyCitationsResponse } from "./types";
1
+ import type { Citation } from "../types/index.js";
2
+ import type { CitationInput, ConvertFileInput, ConvertFileResponse, DeepCitationConfig, FileInput, PrepareConvertedFileOptions, PrepareFilesResult, UploadFileOptions, UploadFileResponse, VerifyCitationsFromLlmOutput, VerifyCitationsOptions, VerifyCitationsResponse } from "./types.js";
3
3
  /**
4
4
  * DeepCitation client for file upload and citation verification.
5
5
  *
@@ -28,13 +28,6 @@ import type { CitationInput, ConvertFileInput, ConvertFileResponse, DeepCitation
28
28
  export declare class DeepCitation {
29
29
  private readonly apiKey;
30
30
  private readonly apiUrl;
31
- /**
32
- * Stores mapping of user-provided fileId to internal attachmentId
33
- * This allows users to reference files by their own IDs
34
- */
35
- private fileIdMap;
36
- /** Store file mapping and return public response */
37
- private storeAndReturnResponse;
38
31
  /**
39
32
  * Create a new DeepCitation client instance.
40
33
  *
@@ -190,17 +183,4 @@ export declare class DeepCitation {
190
183
  verifyCitationsFromLlmOutput(input: VerifyCitationsFromLlmOutput, citations?: {
191
184
  [key: string]: Citation;
192
185
  }): Promise<VerifyCitationsResponse>;
193
- /**
194
- * Register a file that was uploaded separately (e.g., via direct API call).
195
- * This allows you to use verifyCitations with files not uploaded via uploadFile().
196
- *
197
- * @param fileId - Your file ID
198
- * @param attachmentId - The internal attachment ID
199
- */
200
- registerFile(fileId: string, attachmentId: string): void;
201
- /**
202
- * Clear the internal file ID mapping.
203
- * Useful for cleanup or when working with many files.
204
- */
205
- clearFileMap(): void;
206
186
  }
@@ -1,5 +1,5 @@
1
- import { getAllCitationsFromLlmOutput } from "../parsing/parseCitation";
2
- import { generateCitationKey } from "../react/utils";
1
+ import { getAllCitationsFromLlmOutput } from "../parsing/parseCitation.js";
2
+ import { generateCitationKey } from "../react/utils.js";
3
3
  const DEFAULT_API_URL = "https://api.deepcitation.com";
4
4
  /** Convert File/Blob/Buffer to a Blob suitable for FormData */
5
5
  function toBlob(file, filename) {
@@ -18,7 +18,8 @@ function toBlob(file, filename) {
18
18
  /** Extract error message from API response */
19
19
  async function extractErrorMessage(response, fallbackAction) {
20
20
  const error = await response.json().catch(() => ({}));
21
- return error?.error?.message || `${fallbackAction} failed with status ${response.status}`;
21
+ return (error?.error?.message ||
22
+ `${fallbackAction} failed with status ${response.status}`);
22
23
  }
23
24
  /**
24
25
  * DeepCitation client for file upload and citation verification.
@@ -48,17 +49,6 @@ async function extractErrorMessage(response, fallbackAction) {
48
49
  export class DeepCitation {
49
50
  apiKey;
50
51
  apiUrl;
51
- /**
52
- * Stores mapping of user-provided fileId to internal attachmentId
53
- * This allows users to reference files by their own IDs
54
- */
55
- fileIdMap = new Map();
56
- /** Store file mapping and return public response */
57
- storeAndReturnResponse(apiResponse) {
58
- this.fileIdMap.set(apiResponse.fileId, { attachmentId: apiResponse.attachmentId });
59
- const { attachmentId: _, ...publicResponse } = apiResponse;
60
- return publicResponse;
61
- }
62
52
  /**
63
53
  * Create a new DeepCitation client instance.
64
54
  *
@@ -111,7 +101,7 @@ export class DeepCitation {
111
101
  if (!response.ok) {
112
102
  throw new Error(await extractErrorMessage(response, "Upload"));
113
103
  }
114
- return this.storeAndReturnResponse(await response.json());
104
+ return (await response.json());
115
105
  }
116
106
  /**
117
107
  * Convert a URL or Office file to PDF for citation verification.
@@ -179,10 +169,7 @@ export class DeepCitation {
179
169
  if (!response.ok) {
180
170
  throw new Error(await extractErrorMessage(response, "Conversion"));
181
171
  }
182
- const apiResponse = (await response.json());
183
- this.fileIdMap.set(apiResponse.fileId, { attachmentId: apiResponse.attachmentId });
184
- const { attachmentId: _, ...publicResponse } = apiResponse;
185
- return publicResponse;
172
+ return (await response.json());
186
173
  }
187
174
  /**
188
175
  * Prepare a previously converted file for citation verification.
@@ -205,10 +192,6 @@ export class DeepCitation {
205
192
  * ```
206
193
  */
207
194
  async prepareConvertedFile(options) {
208
- const fileInfo = this.fileIdMap.get(options.fileId);
209
- if (!fileInfo) {
210
- throw new Error(`File ID "${options.fileId}" not found. Make sure to call convertToPdf() first.`);
211
- }
212
195
  const response = await fetch(`${this.apiUrl}/prepareFile`, {
213
196
  method: "POST",
214
197
  headers: {
@@ -216,14 +199,13 @@ export class DeepCitation {
216
199
  "Content-Type": "application/json",
217
200
  },
218
201
  body: JSON.stringify({
219
- attachmentId: fileInfo.attachmentId,
220
202
  fileId: options.fileId,
221
203
  }),
222
204
  });
223
205
  if (!response.ok) {
224
206
  throw new Error(await extractErrorMessage(response, "Prepare"));
225
207
  }
226
- return this.storeAndReturnResponse(await response.json());
208
+ return (await response.json());
227
209
  }
228
210
  /**
229
211
  * Upload multiple files for citation verification and get structured content.
@@ -286,11 +268,6 @@ export class DeepCitation {
286
268
  * ```
287
269
  */
288
270
  async verifyCitations(fileId, citations, options) {
289
- // Look up the internal IDs from our map
290
- const fileInfo = this.fileIdMap.get(fileId);
291
- if (!fileInfo) {
292
- throw new Error(`File ID "${fileId}" not found. Make sure to upload the file first with uploadFile().`);
293
- }
294
271
  // Normalize citations to a map with citation keys
295
272
  const citationMap = {};
296
273
  if (Array.isArray(citations)) {
@@ -315,24 +292,27 @@ export class DeepCitation {
315
292
  else {
316
293
  throw new Error("Invalid citations format");
317
294
  }
318
- const response = await fetch(`${this.apiUrl}/verifyCitation`, {
295
+ const requestUrl = `${this.apiUrl}/verifyCitations`;
296
+ const requestBody = {
297
+ data: {
298
+ fileId,
299
+ citations: citationMap,
300
+ outputImageFormat: options?.outputImageFormat || "avif",
301
+ },
302
+ };
303
+ const response = await fetch(requestUrl, {
319
304
  method: "POST",
320
305
  headers: {
321
306
  Authorization: `Bearer ${this.apiKey}`,
322
307
  "Content-Type": "application/json",
323
308
  },
324
- body: JSON.stringify({
325
- data: {
326
- attachmentId: fileInfo.attachmentId,
327
- citations: citationMap,
328
- outputImageFormat: options?.outputImageFormat || "avif",
329
- },
330
- }),
309
+ body: JSON.stringify(requestBody),
331
310
  });
332
311
  if (!response.ok) {
333
312
  throw new Error(await extractErrorMessage(response, "Verification"));
334
313
  }
335
- return (await response.json());
314
+ const result = (await response.json());
315
+ return result;
336
316
  }
337
317
  /**
338
318
  * Verify citations from LLM output with automatic parsing.
@@ -362,9 +342,6 @@ export class DeepCitation {
362
342
  if (Object.keys(citations).length === 0) {
363
343
  return { foundHighlights: {} };
364
344
  }
365
- // Note: fileDataParts is now only used to identify which files to verify
366
- // The mapping from fileId to attachmentId must be registered via uploadFile() or prepareFiles()
367
- // in the same session. For Zero Data Retention scenarios, use verifyCitations() directly.
368
345
  // Group citations by fileId
369
346
  const citationsByFile = new Map();
370
347
  for (const [key, citation] of Object.entries(citations)) {
@@ -374,10 +351,10 @@ export class DeepCitation {
374
351
  }
375
352
  citationsByFile.get(fileId)[key] = citation;
376
353
  }
377
- // Filter to only registered files and verify in parallel
354
+ // Verify all files in parallel
378
355
  const verificationPromises = [];
379
356
  for (const [fileId, fileCitations] of citationsByFile) {
380
- if (this.fileIdMap.has(fileId)) {
357
+ if (fileId) {
381
358
  verificationPromises.push(this.verifyCitations(fileId, fileCitations, { outputImageFormat }));
382
359
  }
383
360
  }
@@ -388,21 +365,4 @@ export class DeepCitation {
388
365
  }
389
366
  return { foundHighlights: allHighlights };
390
367
  }
391
- /**
392
- * Register a file that was uploaded separately (e.g., via direct API call).
393
- * This allows you to use verifyCitations with files not uploaded via uploadFile().
394
- *
395
- * @param fileId - Your file ID
396
- * @param attachmentId - The internal attachment ID
397
- */
398
- registerFile(fileId, attachmentId) {
399
- this.fileIdMap.set(fileId, { attachmentId });
400
- }
401
- /**
402
- * Clear the internal file ID mapping.
403
- * Useful for cleanup or when working with many files.
404
- */
405
- clearFileMap() {
406
- this.fileIdMap.clear();
407
- }
408
368
  }
@@ -1,2 +1,2 @@
1
- export { DeepCitation } from "./DeepCitation";
2
- export type { DeepCitationConfig, UploadFileResponse, UploadFileOptions, VerifyCitationsResponse, VerifyCitationsOptions, CitationInput, FileInput, FileDataPart, PrepareFilesResult, VerifyCitationsFromLlmOutput, ConvertFileInput, ConvertFileResponse, PrepareConvertedFileOptions, } from "./types";
1
+ export { DeepCitation } from "./DeepCitation.js";
2
+ export type { DeepCitationConfig, UploadFileResponse, UploadFileOptions, VerifyCitationsResponse, VerifyCitationsOptions, CitationInput, FileInput, FileDataPart, PrepareFilesResult, VerifyCitationsFromLlmOutput, ConvertFileInput, ConvertFileResponse, PrepareConvertedFileOptions, } from "./types.js";
@@ -1 +1 @@
1
- export { DeepCitation } from "./DeepCitation";
1
+ export { DeepCitation } from "./DeepCitation.js";
@@ -1,4 +1,4 @@
1
- import type { Citation, FoundHighlightLocation } from "../types/index";
1
+ import type { Citation, FoundHighlightLocation } from "../types/index.js";
2
2
  /**
3
3
  * Configuration options for the DeepCitation client
4
4
  */
@@ -1,4 +1,4 @@
1
- export declare const CITATION_MARKDOWN_SYNTAX_PROMPT = "\nCitation syntax to use within Markdown:\n\u2022 To support any ideas or information that requires a citation from the provided content, use the following citation syntax:\n<cite file_id='file_id' start_page_key='page_number_PAGE_index_INDEX' full_phrase='the verbatim text of the terse phrase inside <file_text />; remember to escape quotes and newlines inside the full_phrase to remain as valid JSON' key_span='the verbatim value or words within full_phrase that best support the citation' line_ids='2-6' reasoning='the terse logic used to conclude the citation' />\n\n\u2022 Very important: for page numbers, only use the page number and page index info from the page_number_PAGE_index_INDEX format (e.g. <page_number_1_index_0>) and never from the contents inside the page.\n\u2022 start_page_key, full_phrase, and line_ids are required for each citation.\n\u2022 Infer line_ids, as we only provide the first, last, and every 5th line. When copying a previous <cite />, use the full info from the previous citation without changing the start_page_key, line_ids, or any other <cite /> attributes.\n\u2022 Use refer to line_ids inclusively, and use a range (or single) for each citation, split multiple sequential line_ids into multiple citations.\n\u2022 These citations will be replaced and displayed in-line as a numeric element (e.g. [1]), the markdown preceding <cite /> should read naturally with only one <cite /> per sentence with rare exceptions for two <cite /> in a sentence. <cite /> often present best at the end of the sentence, and are not grouped at the end of the document.\n\u2022 The full_phrase should be the exact verbatim text of the phrase or paragraph from the source document to support the insight or idea.\n\u2022 We do NOT put the full_phrase inside <cite ...></cite>; we only use full_phrase inside the full_phrase attribute.\n";
1
+ export declare const CITATION_MARKDOWN_SYNTAX_PROMPT = "\nCitation syntax to use within Markdown:\n\u2022 To support any ideas or information that requires a citation from the provided content, use the following citation syntax:\n<cite file_id='file_id' start_page_key='page_number_PAGE_index_INDEX' full_phrase='the verbatim text of the terse phrase inside <file_text />; remember to escape quotes and newlines inside the full_phrase to remain as valid JSON' key_span='the verbatim value or 1-3 words within full_phrase that best support the citation' line_ids='2-6' reasoning='the terse logic used to conclude the citation' />\n\n\u2022 Very important: for page numbers, only use the page number and page index info from the page_number_PAGE_index_INDEX format (e.g. <page_number_1_index_0>) and never from the contents inside the page.\n\u2022 start_page_key, full_phrase, and line_ids are required for each citation.\n\u2022 Infer line_ids, as we only provide the first, last, and every 5th line. When copying a previous <cite />, use the full info from the previous citation without changing the start_page_key, line_ids, or any other <cite /> attributes.\n\u2022 Use refer to line_ids inclusively, and use a range (or single) for each citation, split multiple sequential line_ids into multiple citations.\n\u2022 These citations will be replaced and displayed in-line as a numeric element (e.g. [1]), the markdown preceding <cite /> should read naturally with only one <cite /> per sentence with rare exceptions for two <cite /> in a sentence. <cite /> often present best at the end of the sentence, and are not grouped at the end of the document.\n\u2022 The full_phrase should be the exact verbatim text of the phrase or paragraph from the source document to support the insight or idea.\n\u2022 We do NOT put the full_phrase inside <cite ...></cite>; we only use full_phrase inside the full_phrase attribute.\n";
2
2
  export declare const AV_CITATION_MARKDOWN_SYNTAX_PROMPT = "\n\u2022 To support any ideas or information that requires a citation from the provided content, use the following citation syntax:\n<cite file_id='file_id' full_phrase='the verbatim text of the phrase; remember to escape quotes and newlines inside the full_phrase to remain as valid JSON' timestamps='HH:MM:SS.SSS-HH:MM:SS.SSS' reasoning='the logic connecting the form section requirements to the supporting source citation' />\n\u2022 These citations are displayed in-line or in the relevant list item, and are not grouped at the end of the document.\n";
3
3
  export interface WrapSystemPromptOptions {
4
4
  /** The original system prompt to wrap with citation instructions */
@@ -1,7 +1,7 @@
1
1
  export const CITATION_MARKDOWN_SYNTAX_PROMPT = `
2
2
  Citation syntax to use within Markdown:
3
3
  • To support any ideas or information that requires a citation from the provided content, use the following citation syntax:
4
- <cite file_id='file_id' start_page_key='page_number_PAGE_index_INDEX' full_phrase='the verbatim text of the terse phrase inside <file_text />; remember to escape quotes and newlines inside the full_phrase to remain as valid JSON' key_span='the verbatim value or words within full_phrase that best support the citation' line_ids='2-6' reasoning='the terse logic used to conclude the citation' />
4
+ <cite file_id='file_id' start_page_key='page_number_PAGE_index_INDEX' full_phrase='the verbatim text of the terse phrase inside <file_text />; remember to escape quotes and newlines inside the full_phrase to remain as valid JSON' key_span='the verbatim value or 1-3 words within full_phrase that best support the citation' line_ids='2-6' reasoning='the terse logic used to conclude the citation' />
5
5
 
6
6
  • Very important: for page numbers, only use the page number and page index info from the page_number_PAGE_index_INDEX format (e.g. <page_number_1_index_0>) and never from the contents inside the page.
7
7
  • start_page_key, full_phrase, and line_ids are required for each citation.
@@ -125,7 +125,7 @@ export const CITATION_JSON_OUTPUT_FORMAT = {
125
125
  },
126
126
  keySpan: {
127
127
  type: "string",
128
- description: "the verbatim value or words within fullPhrase that best support the citation",
128
+ description: "the verbatim value or 1-3 words within fullPhrase that best support the citation",
129
129
  },
130
130
  lineIds: {
131
131
  type: "array",
@@ -1,3 +1,3 @@
1
- export * from "./promptCompression";
2
- export * from "./citationPrompts";
3
- export * from "./types";
1
+ export * from "./promptCompression.js";
2
+ export * from "./citationPrompts.js";
3
+ export * from "./types.js";
@@ -1,3 +1,3 @@
1
- export * from "./promptCompression";
2
- export * from "./citationPrompts";
3
- export * from "./types";
1
+ export * from "./promptCompression.js";
2
+ export * from "./citationPrompts.js";
3
+ export * from "./types.js";
@@ -1,4 +1,4 @@
1
- import { CompressedResult } from "./types";
1
+ import { CompressedResult } from "./types.js";
2
2
  /**
3
3
  * Compress all occurrences of `ids` inside `obj`, returning a new object
4
4
  * plus the `prefixMap` needed to decompress.
@@ -1,5 +1,5 @@
1
- import { type ScreenBox } from "./boxes";
2
- import { type FoundHighlightLocation } from "./foundHighlight";
1
+ import { type ScreenBox } from "./boxes.js";
2
+ import { type FoundHighlightLocation } from "./foundHighlight.js";
3
3
  export type OutputImageFormat = "jpeg" | "png" | "avif" | undefined | null;
4
4
  export declare const DEFAULT_OUTPUT_IMAGE_FORMAT: "avif";
5
5
  export interface VerifyCitationResponse {
@@ -1,6 +1,6 @@
1
- import { type Citation } from "./citation";
2
- import { type SearchState } from "./search";
3
- import { type PdfSpaceItem } from "./boxes";
1
+ import { type Citation } from "./citation.js";
2
+ import { type SearchState } from "./search.js";
3
+ import { type PdfSpaceItem } from "./boxes.js";
4
4
  export declare const NOT_FOUND_HIGHLIGHT_INDEX = -1;
5
5
  export declare const PENDING_HIGHLIGHT_INDEX = -2;
6
6
  export declare const BLANK_HIGHLIGHT_LOCATION: FoundHighlightLocation;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deepcitation/deepcitation-js",
3
- "version": "1.0.6",
3
+ "version": "1.0.8",
4
4
  "description": "DeepCitation JavaScript SDK for deterministic AI citation verification",
5
5
  "type": "module",
6
6
  "private": false,