@ontos-ai/knowhere-sdk 0.8.0 → 0.9.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.
package/README.md CHANGED
@@ -313,6 +313,30 @@ console.log(serverSearch.references);
313
313
  Local grep and reads use the cached parse result, not server-side chunk scans.
314
314
  Search uses the Knowhere API retrieval query; local document IDs only help map
315
315
  returned server document IDs back to local cache IDs when available.
316
+ If a search result only has a published `documentId`, or an async parse flow only
317
+ has a completed `jobId`, read-oriented helpers can accept that remote identifier
318
+ directly and will sync the result into the local cache before reading. For a
319
+ `documentId`, the SDK resolves the document's current published `jobId` and then
320
+ downloads the parser result ZIP through the same `cacheJobResult(...)` path:
321
+
322
+ ```typescript
323
+ const remoteRead = await client.knowledge.readChunks({
324
+ documentId: 'doc_123',
325
+ sectionPath: 'Overview',
326
+ limit: 5,
327
+ });
328
+
329
+ const remoteOutline = await client.knowledge.getDocumentOutline({
330
+ documentId: 'doc_123',
331
+ });
332
+
333
+ const jobRead = await client.knowledge.readChunks({
334
+ jobId: jobResult.jobId,
335
+ localDocumentId: 'manual-v1',
336
+ limit: 5,
337
+ });
338
+ ```
339
+
316
340
  The MCP package is a wrapper over this SDK interface; install it only when an
317
341
  agent host needs an MCP server. See the MCP package README for Codex, Claude
318
342
  Code, Claude Desktop, and generic stdio MCP host configuration examples.
package/dist/index.d.mts CHANGED
@@ -996,6 +996,20 @@ interface KnowledgeCacheJobResultParams {
996
996
  localDocumentId?: string;
997
997
  verifyChecksum?: boolean;
998
998
  }
999
+ interface KnowledgeCacheDocumentParams {
1000
+ /** Canonical Knowhere document identifier from published retrieval results. */
1001
+ documentId: string;
1002
+ /** Optional local cache identifier to use for the localized document copy. */
1003
+ localDocumentId?: string;
1004
+ }
1005
+ interface KnowledgeDocumentReference {
1006
+ /** Stable local identifier used by cached outline/read/grep methods. */
1007
+ localDocumentId?: string;
1008
+ /** Canonical Knowhere document identifier from published retrieval results. */
1009
+ documentId?: string;
1010
+ /** Server parse job identifier whose completed result should be cached before reading. */
1011
+ jobId?: string;
1012
+ }
999
1013
  interface KnowledgeSection {
1000
1014
  sectionPath: string;
1001
1015
  sectionTitle: string;
@@ -1014,8 +1028,7 @@ interface KnowledgeOutline {
1014
1028
  sections: KnowledgeSection[];
1015
1029
  sectionTree: KnowledgeSection[];
1016
1030
  }
1017
- interface KnowledgeReadParams {
1018
- localDocumentId: string;
1031
+ interface KnowledgeReadParams extends KnowledgeDocumentReference {
1019
1032
  sectionPath?: string;
1020
1033
  startChunk?: number;
1021
1034
  endChunk?: number;
@@ -1038,8 +1051,7 @@ interface KnowledgeReadResponse {
1038
1051
  chunks: KnowledgeReadChunk[];
1039
1052
  nextChunk?: number;
1040
1053
  }
1041
- interface KnowledgeGrepParams {
1042
- localDocumentId: string;
1054
+ interface KnowledgeGrepParams extends KnowledgeDocumentReference {
1043
1055
  pattern: string;
1044
1056
  isRegex?: boolean;
1045
1057
  isCaseSensitive?: boolean;
@@ -1111,13 +1123,17 @@ declare class Knowledge {
1111
1123
  getJobStatus(jobId: string): Promise<KnowledgeAsyncJobStatusResponse>;
1112
1124
  recoverPendingAsyncParseJobs(): Promise<KnowledgeStartupRecoveryResponse>;
1113
1125
  cacheJobResult(params: KnowledgeCacheJobResultParams): Promise<LocalKnowledgeParseResponse>;
1126
+ cacheDocument(params: KnowledgeCacheDocumentParams): Promise<LocalKnowledgeParseResponse>;
1114
1127
  private resolveAsyncCache;
1115
1128
  listDocuments(): Promise<LocalKnowledgeDocument[]>;
1116
- getDocumentOutline(localDocumentId: string): Promise<KnowledgeOutline>;
1129
+ getDocumentOutline(reference: string | KnowledgeDocumentReference): Promise<KnowledgeOutline>;
1117
1130
  readChunks(params: KnowledgeReadParams): Promise<KnowledgeReadResponse>;
1118
1131
  grepChunks(params: KnowledgeGrepParams): Promise<KnowledgeGrepResponse>;
1119
1132
  search(params: KnowledgeSearchParams): Promise<KnowledgeSearchResponse>;
1120
1133
  private resolveSearchDocuments;
1134
+ private loadReadableResult;
1135
+ private findLocalDocumentByRemoteId;
1136
+ private getPublishedDocumentJobId;
1121
1137
  }
1122
1138
 
1123
1139
  interface StoredAsyncParseJob {
@@ -1342,4 +1358,4 @@ declare class JobFailedError extends KnowhereError {
1342
1358
  constructor(message: string, code: string, jobResult: JobResult);
1343
1359
  }
1344
1360
 
1345
- export { APIError, type AuthTokenProvider, AuthenticationError, BadRequestError, type BaseChunk, ChecksumError, type Chunk, ConflictError, type CreateJobParams, type DocType, type Document, type DocumentChunk, type DocumentChunkGetParams, type DocumentChunkListParams, type DocumentChunkListResponse, type DocumentChunkPagination, type DocumentChunkResponse, type DocumentChunkType, type DocumentListResponse, type DocumentMetadata, Documents, type FileIndex, GatewayTimeoutError, type ImageChunk, InternalServerError, InvalidStateError, type Job, type JobError, JobFailedError, type JobResult, type JobStatus, Jobs, Knowhere, KnowhereError, type KnowhereOptions, Knowledge, type KnowledgeAsyncJobStatusResponse, type KnowledgeAsyncParseParams, type KnowledgeAsyncParseResponse, type KnowledgeCacheJobResultParams, type KnowledgeChunkType, type KnowledgeGrepMatch, type KnowledgeGrepParams, type KnowledgeGrepResponse, type KnowledgeOutline, type KnowledgeParseParams, type KnowledgeReadChunk, type KnowledgeReadParams, type KnowledgeReadResponse, type KnowledgeSearchParams, type KnowledgeSearchReference, type KnowledgeSearchResponse, type KnowledgeSearchResult, type KnowledgeSection, type KnowledgeStartupRecoveryResponse, type LoadOptions, type LocalKnowledgeDocument, type LocalKnowledgeParseResponse, LocalKnowledgeStore, type Manifest, NetworkError, NotFoundError, type ParseParams, type ParseResult, type ParsingModel, type ParsingParams, PaymentRequiredError, PermissionDeniedError, type PollProgress, PollingTimeoutError, RateLimitError, Retrieval, type RetrievalChannel, type RetrievalFilterMode, type RetrievalQueryParams, type RetrievalQueryResponse, type RetrievalReferencedChunk, type RetrievalResult, type RetrievalSectionExclusion, type RetrievalSource, ServiceUnavailableError, type Statistics, type TableChunk, type TextChunk, TimeoutError, type UploadParams, type UploadProgress, VERSION, ValidationError, type WaitOptions, type WebhookConfig, Knowhere as default };
1361
+ export { APIError, type AuthTokenProvider, AuthenticationError, BadRequestError, type BaseChunk, ChecksumError, type Chunk, ConflictError, type CreateJobParams, type DocType, type Document, type DocumentChunk, type DocumentChunkGetParams, type DocumentChunkListParams, type DocumentChunkListResponse, type DocumentChunkPagination, type DocumentChunkResponse, type DocumentChunkType, type DocumentListResponse, type DocumentMetadata, Documents, type FileIndex, GatewayTimeoutError, type ImageChunk, InternalServerError, InvalidStateError, type Job, type JobError, JobFailedError, type JobResult, type JobStatus, Jobs, Knowhere, KnowhereError, type KnowhereOptions, Knowledge, type KnowledgeAsyncJobStatusResponse, type KnowledgeAsyncParseParams, type KnowledgeAsyncParseResponse, type KnowledgeCacheDocumentParams, type KnowledgeCacheJobResultParams, type KnowledgeChunkType, type KnowledgeDocumentReference, type KnowledgeGrepMatch, type KnowledgeGrepParams, type KnowledgeGrepResponse, type KnowledgeOutline, type KnowledgeParseParams, type KnowledgeReadChunk, type KnowledgeReadParams, type KnowledgeReadResponse, type KnowledgeSearchParams, type KnowledgeSearchReference, type KnowledgeSearchResponse, type KnowledgeSearchResult, type KnowledgeSection, type KnowledgeStartupRecoveryResponse, type LoadOptions, type LocalKnowledgeDocument, type LocalKnowledgeParseResponse, LocalKnowledgeStore, type Manifest, NetworkError, NotFoundError, type ParseParams, type ParseResult, type ParsingModel, type ParsingParams, PaymentRequiredError, PermissionDeniedError, type PollProgress, PollingTimeoutError, RateLimitError, Retrieval, type RetrievalChannel, type RetrievalFilterMode, type RetrievalQueryParams, type RetrievalQueryResponse, type RetrievalReferencedChunk, type RetrievalResult, type RetrievalSectionExclusion, type RetrievalSource, ServiceUnavailableError, type Statistics, type TableChunk, type TextChunk, TimeoutError, type UploadParams, type UploadProgress, VERSION, ValidationError, type WaitOptions, type WebhookConfig, Knowhere as default };
package/dist/index.d.ts CHANGED
@@ -996,6 +996,20 @@ interface KnowledgeCacheJobResultParams {
996
996
  localDocumentId?: string;
997
997
  verifyChecksum?: boolean;
998
998
  }
999
+ interface KnowledgeCacheDocumentParams {
1000
+ /** Canonical Knowhere document identifier from published retrieval results. */
1001
+ documentId: string;
1002
+ /** Optional local cache identifier to use for the localized document copy. */
1003
+ localDocumentId?: string;
1004
+ }
1005
+ interface KnowledgeDocumentReference {
1006
+ /** Stable local identifier used by cached outline/read/grep methods. */
1007
+ localDocumentId?: string;
1008
+ /** Canonical Knowhere document identifier from published retrieval results. */
1009
+ documentId?: string;
1010
+ /** Server parse job identifier whose completed result should be cached before reading. */
1011
+ jobId?: string;
1012
+ }
999
1013
  interface KnowledgeSection {
1000
1014
  sectionPath: string;
1001
1015
  sectionTitle: string;
@@ -1014,8 +1028,7 @@ interface KnowledgeOutline {
1014
1028
  sections: KnowledgeSection[];
1015
1029
  sectionTree: KnowledgeSection[];
1016
1030
  }
1017
- interface KnowledgeReadParams {
1018
- localDocumentId: string;
1031
+ interface KnowledgeReadParams extends KnowledgeDocumentReference {
1019
1032
  sectionPath?: string;
1020
1033
  startChunk?: number;
1021
1034
  endChunk?: number;
@@ -1038,8 +1051,7 @@ interface KnowledgeReadResponse {
1038
1051
  chunks: KnowledgeReadChunk[];
1039
1052
  nextChunk?: number;
1040
1053
  }
1041
- interface KnowledgeGrepParams {
1042
- localDocumentId: string;
1054
+ interface KnowledgeGrepParams extends KnowledgeDocumentReference {
1043
1055
  pattern: string;
1044
1056
  isRegex?: boolean;
1045
1057
  isCaseSensitive?: boolean;
@@ -1111,13 +1123,17 @@ declare class Knowledge {
1111
1123
  getJobStatus(jobId: string): Promise<KnowledgeAsyncJobStatusResponse>;
1112
1124
  recoverPendingAsyncParseJobs(): Promise<KnowledgeStartupRecoveryResponse>;
1113
1125
  cacheJobResult(params: KnowledgeCacheJobResultParams): Promise<LocalKnowledgeParseResponse>;
1126
+ cacheDocument(params: KnowledgeCacheDocumentParams): Promise<LocalKnowledgeParseResponse>;
1114
1127
  private resolveAsyncCache;
1115
1128
  listDocuments(): Promise<LocalKnowledgeDocument[]>;
1116
- getDocumentOutline(localDocumentId: string): Promise<KnowledgeOutline>;
1129
+ getDocumentOutline(reference: string | KnowledgeDocumentReference): Promise<KnowledgeOutline>;
1117
1130
  readChunks(params: KnowledgeReadParams): Promise<KnowledgeReadResponse>;
1118
1131
  grepChunks(params: KnowledgeGrepParams): Promise<KnowledgeGrepResponse>;
1119
1132
  search(params: KnowledgeSearchParams): Promise<KnowledgeSearchResponse>;
1120
1133
  private resolveSearchDocuments;
1134
+ private loadReadableResult;
1135
+ private findLocalDocumentByRemoteId;
1136
+ private getPublishedDocumentJobId;
1121
1137
  }
1122
1138
 
1123
1139
  interface StoredAsyncParseJob {
@@ -1342,4 +1358,4 @@ declare class JobFailedError extends KnowhereError {
1342
1358
  constructor(message: string, code: string, jobResult: JobResult);
1343
1359
  }
1344
1360
 
1345
- export { APIError, type AuthTokenProvider, AuthenticationError, BadRequestError, type BaseChunk, ChecksumError, type Chunk, ConflictError, type CreateJobParams, type DocType, type Document, type DocumentChunk, type DocumentChunkGetParams, type DocumentChunkListParams, type DocumentChunkListResponse, type DocumentChunkPagination, type DocumentChunkResponse, type DocumentChunkType, type DocumentListResponse, type DocumentMetadata, Documents, type FileIndex, GatewayTimeoutError, type ImageChunk, InternalServerError, InvalidStateError, type Job, type JobError, JobFailedError, type JobResult, type JobStatus, Jobs, Knowhere, KnowhereError, type KnowhereOptions, Knowledge, type KnowledgeAsyncJobStatusResponse, type KnowledgeAsyncParseParams, type KnowledgeAsyncParseResponse, type KnowledgeCacheJobResultParams, type KnowledgeChunkType, type KnowledgeGrepMatch, type KnowledgeGrepParams, type KnowledgeGrepResponse, type KnowledgeOutline, type KnowledgeParseParams, type KnowledgeReadChunk, type KnowledgeReadParams, type KnowledgeReadResponse, type KnowledgeSearchParams, type KnowledgeSearchReference, type KnowledgeSearchResponse, type KnowledgeSearchResult, type KnowledgeSection, type KnowledgeStartupRecoveryResponse, type LoadOptions, type LocalKnowledgeDocument, type LocalKnowledgeParseResponse, LocalKnowledgeStore, type Manifest, NetworkError, NotFoundError, type ParseParams, type ParseResult, type ParsingModel, type ParsingParams, PaymentRequiredError, PermissionDeniedError, type PollProgress, PollingTimeoutError, RateLimitError, Retrieval, type RetrievalChannel, type RetrievalFilterMode, type RetrievalQueryParams, type RetrievalQueryResponse, type RetrievalReferencedChunk, type RetrievalResult, type RetrievalSectionExclusion, type RetrievalSource, ServiceUnavailableError, type Statistics, type TableChunk, type TextChunk, TimeoutError, type UploadParams, type UploadProgress, VERSION, ValidationError, type WaitOptions, type WebhookConfig, Knowhere as default };
1361
+ export { APIError, type AuthTokenProvider, AuthenticationError, BadRequestError, type BaseChunk, ChecksumError, type Chunk, ConflictError, type CreateJobParams, type DocType, type Document, type DocumentChunk, type DocumentChunkGetParams, type DocumentChunkListParams, type DocumentChunkListResponse, type DocumentChunkPagination, type DocumentChunkResponse, type DocumentChunkType, type DocumentListResponse, type DocumentMetadata, Documents, type FileIndex, GatewayTimeoutError, type ImageChunk, InternalServerError, InvalidStateError, type Job, type JobError, JobFailedError, type JobResult, type JobStatus, Jobs, Knowhere, KnowhereError, type KnowhereOptions, Knowledge, type KnowledgeAsyncJobStatusResponse, type KnowledgeAsyncParseParams, type KnowledgeAsyncParseResponse, type KnowledgeCacheDocumentParams, type KnowledgeCacheJobResultParams, type KnowledgeChunkType, type KnowledgeDocumentReference, type KnowledgeGrepMatch, type KnowledgeGrepParams, type KnowledgeGrepResponse, type KnowledgeOutline, type KnowledgeParseParams, type KnowledgeReadChunk, type KnowledgeReadParams, type KnowledgeReadResponse, type KnowledgeSearchParams, type KnowledgeSearchReference, type KnowledgeSearchResponse, type KnowledgeSearchResult, type KnowledgeSection, type KnowledgeStartupRecoveryResponse, type LoadOptions, type LocalKnowledgeDocument, type LocalKnowledgeParseResponse, LocalKnowledgeStore, type Manifest, NetworkError, NotFoundError, type ParseParams, type ParseResult, type ParsingModel, type ParsingParams, PaymentRequiredError, PermissionDeniedError, type PollProgress, PollingTimeoutError, RateLimitError, Retrieval, type RetrievalChannel, type RetrievalFilterMode, type RetrievalQueryParams, type RetrievalQueryResponse, type RetrievalReferencedChunk, type RetrievalResult, type RetrievalSectionExclusion, type RetrievalSource, ServiceUnavailableError, type Statistics, type TableChunk, type TextChunk, TimeoutError, type UploadParams, type UploadProgress, VERSION, ValidationError, type WaitOptions, type WebhookConfig, Knowhere as default };
package/dist/index.js CHANGED
@@ -1506,6 +1506,9 @@ var Documents = class extends BaseResource {
1506
1506
  }
1507
1507
  };
1508
1508
 
1509
+ // src/knowledge/knowledge.ts
1510
+ var import_crypto2 = require("crypto");
1511
+
1509
1512
  // src/knowledge/local-store.ts
1510
1513
  var import_crypto = require("crypto");
1511
1514
  var import_os = __toESM(require("os"));
@@ -1734,6 +1737,8 @@ var MAX_READ_LIMIT = 40;
1734
1737
  var DEFAULT_GREP_LIMIT = 20;
1735
1738
  var MAX_GREP_LIMIT = 50;
1736
1739
  var DEFAULT_CONTEXT_CHARS = 80;
1740
+ var SAFE_LOCAL_DOCUMENT_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
1741
+ var REMOTE_DOCUMENT_ID_PATTERN = /^doc[_-]/;
1737
1742
  var Knowledge = class _Knowledge {
1738
1743
  client;
1739
1744
  store;
@@ -1789,6 +1794,19 @@ var Knowledge = class _Knowledge {
1789
1794
  });
1790
1795
  return { document, result };
1791
1796
  }
1797
+ async cacheDocument(params) {
1798
+ if (!params.documentId) {
1799
+ throw new ValidationError("documentId is required");
1800
+ }
1801
+ const existing = await this.findLocalDocumentByRemoteId(
1802
+ params.documentId
1803
+ );
1804
+ const jobId = await this.getPublishedDocumentJobId(params.documentId);
1805
+ return this.cacheJobResult({
1806
+ jobId,
1807
+ localDocumentId: params.localDocumentId ?? existing?.localDocumentId ?? createLocalDocumentIdForRemote(params.documentId)
1808
+ });
1809
+ }
1792
1810
  async resolveAsyncCache(jobId, isDone, isFailed) {
1793
1811
  const trackedJob = await this.store.getAsyncParseJob(jobId);
1794
1812
  if (!trackedJob) {
@@ -1845,8 +1863,8 @@ var Knowledge = class _Knowledge {
1845
1863
  async listDocuments() {
1846
1864
  return this.store.listDocuments();
1847
1865
  }
1848
- async getDocumentOutline(localDocumentId) {
1849
- const { document, result } = await this.store.loadResult(localDocumentId);
1866
+ async getDocumentOutline(reference) {
1867
+ const { document, result } = await this.loadReadableResult(reference);
1850
1868
  const chunks = indexChunks(result);
1851
1869
  const sections = buildFlatSections(result, chunks);
1852
1870
  const sectionTree = result.docNav?.sections && result.docNav.sections.length > 0 ? result.docNav.sections.map(
@@ -1861,7 +1879,7 @@ var Knowledge = class _Knowledge {
1861
1879
  };
1862
1880
  }
1863
1881
  async readChunks(params) {
1864
- const { document, result } = await this.store.loadResult(params.localDocumentId);
1882
+ const { document, result } = await this.loadReadableResult(params);
1865
1883
  const limit = clampLimit(params.limit, DEFAULT_READ_LIMIT, MAX_READ_LIMIT);
1866
1884
  const chunks = indexChunks(result).filter((chunk) => matchesReadScope(chunk, params));
1867
1885
  const selected = selectReadWindow(chunks, params, limit);
@@ -1877,7 +1895,7 @@ var Knowledge = class _Knowledge {
1877
1895
  if (!params.pattern) {
1878
1896
  throw new ValidationError("pattern is required");
1879
1897
  }
1880
- const { document, result } = await this.store.loadResult(params.localDocumentId);
1898
+ const { document, result } = await this.loadReadableResult(params);
1881
1899
  const maxResults = clampLimit(params.maxResults, DEFAULT_GREP_LIMIT, MAX_GREP_LIMIT);
1882
1900
  const contextChars = params.contextChars ?? DEFAULT_CONTEXT_CHARS;
1883
1901
  const matcher = createMatcher(params);
@@ -1947,7 +1965,68 @@ var Knowledge = class _Knowledge {
1947
1965
  const requested = new Set(localDocumentIds);
1948
1966
  return documents.filter((document) => requested.has(document.localDocumentId));
1949
1967
  }
1968
+ async loadReadableResult(reference) {
1969
+ const normalized = normalizeDocumentReference(reference);
1970
+ if (normalized.documentId) {
1971
+ return this.cacheDocument({
1972
+ documentId: normalized.documentId,
1973
+ localDocumentId: normalized.localDocumentId
1974
+ });
1975
+ }
1976
+ if (normalized.jobId) {
1977
+ return this.cacheJobResult({
1978
+ jobId: normalized.jobId,
1979
+ localDocumentId: normalized.localDocumentId
1980
+ });
1981
+ }
1982
+ if (!normalized.localDocumentId) {
1983
+ throw new ValidationError("localDocumentId, documentId, or jobId is required");
1984
+ }
1985
+ const document = await this.store.getDocument(normalized.localDocumentId);
1986
+ if (document) {
1987
+ return this.store.loadResult(normalized.localDocumentId);
1988
+ }
1989
+ if (looksLikeRemoteDocumentId(normalized.localDocumentId)) {
1990
+ return this.cacheDocument({
1991
+ documentId: normalized.localDocumentId,
1992
+ localDocumentId: createLocalDocumentIdForRemote(normalized.localDocumentId)
1993
+ });
1994
+ }
1995
+ throw new Error(`Local Knowhere document not found: ${normalized.localDocumentId}`);
1996
+ }
1997
+ async findLocalDocumentByRemoteId(documentId) {
1998
+ const documents = await this.store.listDocuments();
1999
+ return documents.find((document) => document.documentId === documentId);
2000
+ }
2001
+ async getPublishedDocumentJobId(documentId) {
2002
+ const response = await this.client.documents.listChunks(documentId, {
2003
+ page: 1,
2004
+ pageSize: 1
2005
+ });
2006
+ if (!response.jobId) {
2007
+ throw new Error(
2008
+ `Cannot sync server document ${documentId}: current published job id was not returned.`
2009
+ );
2010
+ }
2011
+ return response.jobId;
2012
+ }
1950
2013
  };
2014
+ function normalizeDocumentReference(reference) {
2015
+ if (typeof reference === "string") {
2016
+ return { localDocumentId: reference };
2017
+ }
2018
+ return reference;
2019
+ }
2020
+ function looksLikeRemoteDocumentId(value) {
2021
+ return REMOTE_DOCUMENT_ID_PATTERN.test(value);
2022
+ }
2023
+ function createLocalDocumentIdForRemote(documentId) {
2024
+ if (SAFE_LOCAL_DOCUMENT_ID_PATTERN.test(documentId) && !documentId.includes("..") && !documentId.includes("/") && !documentId.includes("\\")) {
2025
+ return documentId;
2026
+ }
2027
+ const hash = (0, import_crypto2.createHash)("sha256").update(documentId).digest("hex").slice(0, 16);
2028
+ return `remote_${hash}`;
2029
+ }
1951
2030
  function indexChunks(result) {
1952
2031
  return result.chunks.map((chunk, index) => {
1953
2032
  const filePath = getChunkFilePath2(chunk);
package/dist/index.mjs CHANGED
@@ -1446,6 +1446,9 @@ var Documents = class extends BaseResource {
1446
1446
  }
1447
1447
  };
1448
1448
 
1449
+ // src/knowledge/knowledge.ts
1450
+ import { createHash as createHash2 } from "crypto";
1451
+
1449
1452
  // src/knowledge/local-store.ts
1450
1453
  import { createHash } from "crypto";
1451
1454
  import os from "os";
@@ -1674,6 +1677,8 @@ var MAX_READ_LIMIT = 40;
1674
1677
  var DEFAULT_GREP_LIMIT = 20;
1675
1678
  var MAX_GREP_LIMIT = 50;
1676
1679
  var DEFAULT_CONTEXT_CHARS = 80;
1680
+ var SAFE_LOCAL_DOCUMENT_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
1681
+ var REMOTE_DOCUMENT_ID_PATTERN = /^doc[_-]/;
1677
1682
  var Knowledge = class _Knowledge {
1678
1683
  client;
1679
1684
  store;
@@ -1729,6 +1734,19 @@ var Knowledge = class _Knowledge {
1729
1734
  });
1730
1735
  return { document, result };
1731
1736
  }
1737
+ async cacheDocument(params) {
1738
+ if (!params.documentId) {
1739
+ throw new ValidationError("documentId is required");
1740
+ }
1741
+ const existing = await this.findLocalDocumentByRemoteId(
1742
+ params.documentId
1743
+ );
1744
+ const jobId = await this.getPublishedDocumentJobId(params.documentId);
1745
+ return this.cacheJobResult({
1746
+ jobId,
1747
+ localDocumentId: params.localDocumentId ?? existing?.localDocumentId ?? createLocalDocumentIdForRemote(params.documentId)
1748
+ });
1749
+ }
1732
1750
  async resolveAsyncCache(jobId, isDone, isFailed) {
1733
1751
  const trackedJob = await this.store.getAsyncParseJob(jobId);
1734
1752
  if (!trackedJob) {
@@ -1785,8 +1803,8 @@ var Knowledge = class _Knowledge {
1785
1803
  async listDocuments() {
1786
1804
  return this.store.listDocuments();
1787
1805
  }
1788
- async getDocumentOutline(localDocumentId) {
1789
- const { document, result } = await this.store.loadResult(localDocumentId);
1806
+ async getDocumentOutline(reference) {
1807
+ const { document, result } = await this.loadReadableResult(reference);
1790
1808
  const chunks = indexChunks(result);
1791
1809
  const sections = buildFlatSections(result, chunks);
1792
1810
  const sectionTree = result.docNav?.sections && result.docNav.sections.length > 0 ? result.docNav.sections.map(
@@ -1801,7 +1819,7 @@ var Knowledge = class _Knowledge {
1801
1819
  };
1802
1820
  }
1803
1821
  async readChunks(params) {
1804
- const { document, result } = await this.store.loadResult(params.localDocumentId);
1822
+ const { document, result } = await this.loadReadableResult(params);
1805
1823
  const limit = clampLimit(params.limit, DEFAULT_READ_LIMIT, MAX_READ_LIMIT);
1806
1824
  const chunks = indexChunks(result).filter((chunk) => matchesReadScope(chunk, params));
1807
1825
  const selected = selectReadWindow(chunks, params, limit);
@@ -1817,7 +1835,7 @@ var Knowledge = class _Knowledge {
1817
1835
  if (!params.pattern) {
1818
1836
  throw new ValidationError("pattern is required");
1819
1837
  }
1820
- const { document, result } = await this.store.loadResult(params.localDocumentId);
1838
+ const { document, result } = await this.loadReadableResult(params);
1821
1839
  const maxResults = clampLimit(params.maxResults, DEFAULT_GREP_LIMIT, MAX_GREP_LIMIT);
1822
1840
  const contextChars = params.contextChars ?? DEFAULT_CONTEXT_CHARS;
1823
1841
  const matcher = createMatcher(params);
@@ -1887,7 +1905,68 @@ var Knowledge = class _Knowledge {
1887
1905
  const requested = new Set(localDocumentIds);
1888
1906
  return documents.filter((document) => requested.has(document.localDocumentId));
1889
1907
  }
1908
+ async loadReadableResult(reference) {
1909
+ const normalized = normalizeDocumentReference(reference);
1910
+ if (normalized.documentId) {
1911
+ return this.cacheDocument({
1912
+ documentId: normalized.documentId,
1913
+ localDocumentId: normalized.localDocumentId
1914
+ });
1915
+ }
1916
+ if (normalized.jobId) {
1917
+ return this.cacheJobResult({
1918
+ jobId: normalized.jobId,
1919
+ localDocumentId: normalized.localDocumentId
1920
+ });
1921
+ }
1922
+ if (!normalized.localDocumentId) {
1923
+ throw new ValidationError("localDocumentId, documentId, or jobId is required");
1924
+ }
1925
+ const document = await this.store.getDocument(normalized.localDocumentId);
1926
+ if (document) {
1927
+ return this.store.loadResult(normalized.localDocumentId);
1928
+ }
1929
+ if (looksLikeRemoteDocumentId(normalized.localDocumentId)) {
1930
+ return this.cacheDocument({
1931
+ documentId: normalized.localDocumentId,
1932
+ localDocumentId: createLocalDocumentIdForRemote(normalized.localDocumentId)
1933
+ });
1934
+ }
1935
+ throw new Error(`Local Knowhere document not found: ${normalized.localDocumentId}`);
1936
+ }
1937
+ async findLocalDocumentByRemoteId(documentId) {
1938
+ const documents = await this.store.listDocuments();
1939
+ return documents.find((document) => document.documentId === documentId);
1940
+ }
1941
+ async getPublishedDocumentJobId(documentId) {
1942
+ const response = await this.client.documents.listChunks(documentId, {
1943
+ page: 1,
1944
+ pageSize: 1
1945
+ });
1946
+ if (!response.jobId) {
1947
+ throw new Error(
1948
+ `Cannot sync server document ${documentId}: current published job id was not returned.`
1949
+ );
1950
+ }
1951
+ return response.jobId;
1952
+ }
1890
1953
  };
1954
+ function normalizeDocumentReference(reference) {
1955
+ if (typeof reference === "string") {
1956
+ return { localDocumentId: reference };
1957
+ }
1958
+ return reference;
1959
+ }
1960
+ function looksLikeRemoteDocumentId(value) {
1961
+ return REMOTE_DOCUMENT_ID_PATTERN.test(value);
1962
+ }
1963
+ function createLocalDocumentIdForRemote(documentId) {
1964
+ if (SAFE_LOCAL_DOCUMENT_ID_PATTERN.test(documentId) && !documentId.includes("..") && !documentId.includes("/") && !documentId.includes("\\")) {
1965
+ return documentId;
1966
+ }
1967
+ const hash = createHash2("sha256").update(documentId).digest("hex").slice(0, 16);
1968
+ return `remote_${hash}`;
1969
+ }
1891
1970
  function indexChunks(result) {
1892
1971
  return result.chunks.map((chunk, index) => {
1893
1972
  const filePath = getChunkFilePath2(chunk);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ontos-ai/knowhere-sdk",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "description": "Official Node.js SDK for Knowhere document parsing API",
5
5
  "keywords": [
6
6
  "knowhere",