@kortexya/reasoninglayer 5.0.0 → 5.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.
package/dist/index.js CHANGED
@@ -5,7 +5,7 @@ var __export = (target, all) => {
5
5
  };
6
6
 
7
7
  // src/config.ts
8
- var SDK_VERSION = "5.0.0";
8
+ var SDK_VERSION = "5.1.0";
9
9
  function resolveConfig(config) {
10
10
  if (!config.baseUrl) {
11
11
  throw new Error("ClientConfig.baseUrl is required");
@@ -950,6 +950,8 @@ function toSnakeCase(input) {
950
950
 
951
951
  // src/http.ts
952
952
  var RAW_BODY_HEADER = "X-RL-Raw-Body";
953
+ var BINARY_BODY_HEADER = "X-RL-Binary-Body";
954
+ var BINARY_BODY_PART = "body";
953
955
 
954
956
  // src/utils/audit-headers.ts
955
957
  var AUDIT_CAUSAL_REQUEST_HEADERS = {
@@ -1178,6 +1180,18 @@ function buildAuthHeaders(config) {
1178
1180
  }
1179
1181
  function transformRequestInit(init) {
1180
1182
  if (!init) return init;
1183
+ const binaryType = findHeader(init.headers, BINARY_BODY_HEADER_LOWER);
1184
+ if (binaryType !== void 0) {
1185
+ return {
1186
+ ...init,
1187
+ headers: withHeader(
1188
+ withoutHeader(init.headers, BINARY_BODY_HEADER_LOWER),
1189
+ "Content-Type",
1190
+ binaryType
1191
+ ),
1192
+ body: binaryBody(init.body)
1193
+ };
1194
+ }
1181
1195
  if (hasRawBodyHeader(init.headers)) {
1182
1196
  return { ...init, headers: withoutRawBodyHeader(init.headers) };
1183
1197
  }
@@ -1190,6 +1204,31 @@ function transformRequestInit(init) {
1190
1204
  return init;
1191
1205
  }
1192
1206
  }
1207
+ var BINARY_BODY_HEADER_LOWER = BINARY_BODY_HEADER.toLowerCase();
1208
+ function binaryBody(body) {
1209
+ if (body instanceof FormData) {
1210
+ const parts = [];
1211
+ body.forEach((value, name) => parts.push([name, value]));
1212
+ const only = parts[0];
1213
+ if (parts.length === 1 && only !== void 0 && only[0] === BINARY_BODY_PART) {
1214
+ const value = only[1];
1215
+ if (value instanceof Blob) return value;
1216
+ }
1217
+ }
1218
+ throw new ValidationError(
1219
+ `A ${BINARY_BODY_HEADER} request must carry exactly one Blob part named "${BINARY_BODY_PART}"`
1220
+ );
1221
+ }
1222
+ function withHeader(headers, name, value) {
1223
+ const lowerName = name.toLowerCase();
1224
+ const rest = withoutHeader(headers, lowerName);
1225
+ if (rest instanceof Headers) {
1226
+ rest.set(name, value);
1227
+ return rest;
1228
+ }
1229
+ if (Array.isArray(rest)) return [...rest, [name, value]];
1230
+ return { ...rest, [name]: value };
1231
+ }
1193
1232
  var REQUEST_BUDGET_HEADER_LOWER = REQUEST_BUDGET_HEADER.toLowerCase();
1194
1233
  function readRequestBudget(headers) {
1195
1234
  const raw = findHeader(headers, REQUEST_BUDGET_HEADER_LOWER);
@@ -9354,11 +9393,11 @@ var Analysis = class {
9354
9393
  ...params
9355
9394
  });
9356
9395
  /**
9357
- * @description The exploration must be complete (no more questions) before calling this. Creates appropriateness sorts in the hierarchy from the Duquenne-Guigues basis.
9396
+ * @description The exploration must be complete (no more questions) before calling this. Registration happens before the terminal commit and ignores existing names, so a retry after a lost commit is safe. The committed receipt is retained: completing again returns it unchanged. `rules_created` counts those sort registrations; no inference rule is installed.
9358
9397
  *
9359
9398
  * @tags analysis
9360
9399
  * @name CompleteExploration
9361
- * @summary Complete the exploration and create sort rules from confirmed implications.
9400
+ * @summary Complete the exploration and register appropriateness sorts for its basis.
9362
9401
  * @request POST:/api/v1/analysis/attribute-exploration/{session_id}/complete
9363
9402
  */
9364
9403
  completeExploration = (sessionId, params = {}) => this.http.request({
@@ -9368,7 +9407,7 @@ var Analysis = class {
9368
9407
  ...params
9369
9408
  });
9370
9409
  /**
9371
- * @description The body names the question being confirmed. The check and the mutation run under one session write lock, so an answer is applied at most once.
9410
+ * @description The body names the question being confirmed. The answer commits only on top of the session version it was checked against, so across every server sharing the repository an answer is applied at most once.
9372
9411
  *
9373
9412
  * @tags analysis
9374
9413
  * @name ConfirmImplication
@@ -39998,6 +40037,51 @@ function IngestAudioResponseFromApiToFront(dto) {
39998
40037
  translatedLang: dto.translated_lang ?? void 0
39999
40038
  };
40000
40039
  }
40040
+ function CreateRdfUploadRequestFromFrontToApi(request) {
40041
+ return {
40042
+ name: request.name,
40043
+ size: request.size,
40044
+ ...request.datasetScope !== void 0 && { dataset_scope: request.datasetScope }
40045
+ };
40046
+ }
40047
+ function RdfUploadFromApiToFront(dto) {
40048
+ return {
40049
+ id: dto.id,
40050
+ name: dto.name,
40051
+ size: dto.size,
40052
+ uploadedBytes: dto.uploaded_bytes,
40053
+ chunkBytes: dto.chunk_bytes,
40054
+ chunkSha256: dto.chunk_sha256,
40055
+ sha256: dto.sha256,
40056
+ engineBinarySha256: dto.engine_binary_sha256,
40057
+ format: dto.format,
40058
+ gzip: dto.gzip,
40059
+ status: dto.status,
40060
+ ownerId: dto.owner_id,
40061
+ sessionId: dto.session_id,
40062
+ documentId: dto.document_id,
40063
+ datasetScope: dto.dataset_scope,
40064
+ prefixBindings: definedRecord(dto.prefix_bindings ?? {}),
40065
+ quadsCommitted: dto.quads_committed,
40066
+ batchesCommitted: dto.batches_committed,
40067
+ resourcesCreated: dto.resources_created,
40068
+ sortsCreated: dto.sorts_created,
40069
+ error: dto.error,
40070
+ updatedAt: dto.updated_at
40071
+ };
40072
+ }
40073
+ function RdfUploadChunkReceiptFromApiToFront(dto) {
40074
+ return {
40075
+ uploadedBytes: dto.uploaded_bytes,
40076
+ sha256: dto.sha256
40077
+ };
40078
+ }
40079
+ function RdfUploadPauseReceiptFromApiToFront(dto) {
40080
+ return {
40081
+ id: dto.id,
40082
+ status: dto.status
40083
+ };
40084
+ }
40001
40085
 
40002
40086
  // src/resources/ingestion-session.ts
40003
40087
  var IngestionFailedError = class extends ReasoningLayerError {
@@ -41283,6 +41367,208 @@ var IngestionClient = class {
41283
41367
  const response = await this.api.resumeAudioJob(jobId, toRequestParams(requestOptions));
41284
41368
  return decodeResponse(response, IngestAudioResponseFromApiToFront);
41285
41369
  }
41370
+ /**
41371
+ * Open a resumable upload of one original RDF file —
41372
+ * `POST /api/v1/ingest/rdf/uploads`.
41373
+ *
41374
+ * @param request - The file name (its extension selects the format), its
41375
+ * exact size, and an optional shared N-Triples/N-Quads dataset scope.
41376
+ * @param requestOptions - Per-call request options.
41377
+ * @returns The new upload (HTTP 201), with `status: 'uploading'`,
41378
+ * `uploadedBytes: 0` and the `chunkBytes` every chunk must respect.
41379
+ * @throws {BadRequestError} 400 when the name is empty, longer than 255
41380
+ * bytes or holds `/`, `\` or NUL; when the size is 0 or above 32 GiB; when
41381
+ * the extension names no RDF format; or when a dataset scope accompanies a
41382
+ * format other than N-Triples or N-Quads.
41383
+ *
41384
+ * @remarks
41385
+ * Body is snake_case on the wire (`dataset_scope`). The engine keeps the
41386
+ * uploaded bytes verbatim and parses them only when
41387
+ * {@link IngestionClient.completeRdfUpload} starts the import. Send the
41388
+ * bytes with {@link IngestionClient.uploadRdfChunk}.
41389
+ *
41390
+ * @example
41391
+ * ```typescript
41392
+ * const upload = await client.ingestion.createRdfUpload({
41393
+ * name: file.name,
41394
+ * size: file.size,
41395
+ * });
41396
+ * for (let offset = 0; offset < file.size; offset += upload.chunkBytes) {
41397
+ * await client.ingestion.uploadRdfChunk(
41398
+ * upload.id,
41399
+ * offset,
41400
+ * file.slice(offset, offset + upload.chunkBytes),
41401
+ * );
41402
+ * }
41403
+ * await client.ingestion.completeRdfUpload(upload.id);
41404
+ * ```
41405
+ */
41406
+ async createRdfUpload(request, requestOptions) {
41407
+ const response = await this.api.create(
41408
+ CreateRdfUploadRequestFromFrontToApi(request),
41409
+ toRequestParams(requestOptions)
41410
+ );
41411
+ return decodeResponse(response, RdfUploadFromApiToFront);
41412
+ }
41413
+ /**
41414
+ * List the tenant's original RDF uploads — `GET /api/v1/ingest/rdf/uploads`.
41415
+ *
41416
+ * @param requestOptions - Per-call request options.
41417
+ * @returns Every RDF upload of the tenant, the most recently updated first.
41418
+ * Each `chunkSha256` is empty in this listing; read one upload with
41419
+ * {@link IngestionClient.getRdfUpload} for its chunk digests.
41420
+ * @throws {ApiError} If the request fails.
41421
+ *
41422
+ * @remarks
41423
+ * Response is snake_case on the wire. An import that reads `queued` or
41424
+ * `processing` without a live worker is reported as `interrupted`.
41425
+ *
41426
+ * @example
41427
+ * ```typescript
41428
+ * const uploads = await client.ingestion.listRdfUploads();
41429
+ * const interrupted = uploads.filter((u) => u.status === 'interrupted');
41430
+ * ```
41431
+ */
41432
+ async listRdfUploads(requestOptions) {
41433
+ const response = await this.api.list(toRequestParams(requestOptions));
41434
+ return decodeResponse(response, (dto) => dto.map(RdfUploadFromApiToFront));
41435
+ }
41436
+ /**
41437
+ * Read one RDF upload: its upload extent and its durable ingestion
41438
+ * checkpoint — `GET /api/v1/ingest/rdf/uploads/{id}`.
41439
+ *
41440
+ * @param id - The upload id ({@link RdfUpload.id}).
41441
+ * @param requestOptions - Per-call request options.
41442
+ * @returns The upload, with the SHA-256 of every stored chunk.
41443
+ * @throws {NotFoundError} 404 when the tenant has no RDF upload with this id.
41444
+ *
41445
+ * @remarks
41446
+ * Response is snake_case on the wire. Use `uploadedBytes` to resume an
41447
+ * interrupted upload at the right offset, and `status` to follow the
41448
+ * import; `interrupted` means no worker runs it, and
41449
+ * {@link IngestionClient.completeRdfUpload} resumes it.
41450
+ *
41451
+ * @example
41452
+ * ```typescript
41453
+ * const upload = await client.ingestion.getRdfUpload(id);
41454
+ * const nextOffset = upload.uploadedBytes;
41455
+ * ```
41456
+ */
41457
+ async getRdfUpload(id, requestOptions) {
41458
+ const response = await this.api.get(id, toRequestParams(requestOptions));
41459
+ return decodeResponse(response, RdfUploadFromApiToFront);
41460
+ }
41461
+ /**
41462
+ * Store one chunk of an RDF upload durably —
41463
+ * `PUT /api/v1/ingest/rdf/uploads/{id}?offset=…`.
41464
+ *
41465
+ * @param id - The upload id ({@link RdfUpload.id}).
41466
+ * @param offset - The byte offset of the chunk in the file: a multiple of
41467
+ * {@link RdfUpload.chunkBytes}, equal to `uploadedBytes` for a new chunk.
41468
+ * @param chunk - The chunk's bytes: exactly `chunkBytes` of them, except for
41469
+ * the last chunk of the file. A `File` slice (`file.slice(start, end)`) is
41470
+ * a `Blob`; wrap other bytes as `new Blob([bytes])`.
41471
+ * @param requestOptions - Per-call request options.
41472
+ * @returns The bytes stored so far and the SHA-256 of this chunk.
41473
+ * @throws {BadRequestError} 400 when the upload no longer accepts bytes, when
41474
+ * the offset or chunk size breaks the rules above, when the offset skips
41475
+ * or precedes the stored extent, or when a resent chunk differs from the
41476
+ * bytes stored at that offset.
41477
+ * @throws {ForbiddenError} 403 when the caller did not open the upload.
41478
+ * @throws {NotFoundError} 404 when the tenant has no RDF upload with this id.
41479
+ *
41480
+ * @remarks
41481
+ * The body is the raw bytes, sent as `application/octet-stream`; the
41482
+ * response is snake_case on the wire. Resending a chunk the engine already
41483
+ * stored, with the same bytes, answers the same receipt, so a retry after a
41484
+ * lost response is safe.
41485
+ *
41486
+ * @example
41487
+ * ```typescript
41488
+ * const upload = await client.ingestion.getRdfUpload(id);
41489
+ * const start = upload.uploadedBytes;
41490
+ * const receipt = await client.ingestion.uploadRdfChunk(
41491
+ * id,
41492
+ * start,
41493
+ * file.slice(start, start + upload.chunkBytes),
41494
+ * );
41495
+ * console.log(receipt.uploadedBytes, receipt.sha256);
41496
+ * ```
41497
+ */
41498
+ async uploadRdfChunk(id, offset, chunk, requestOptions) {
41499
+ const body = new FormData();
41500
+ body.append(BINARY_BODY_PART, chunk);
41501
+ const response = await this.api.http.request({
41502
+ ...mergeRequestParams(
41503
+ { headers: { [BINARY_BODY_HEADER]: "application/octet-stream" } },
41504
+ requestOptions
41505
+ ),
41506
+ path: `/api/v1/ingest/rdf/uploads/${encodeURIComponent(id)}`,
41507
+ method: "PUT",
41508
+ query: { offset },
41509
+ body,
41510
+ type: "multipart/form-data",
41511
+ format: "json"
41512
+ });
41513
+ return decodeResponse(response, RdfUploadChunkReceiptFromApiToFront);
41514
+ }
41515
+ /**
41516
+ * Start, or resume, the import of a fully uploaded RDF file —
41517
+ * `POST /api/v1/ingest/rdf/uploads/{id}/complete`.
41518
+ *
41519
+ * @param id - The upload id ({@link RdfUpload.id}).
41520
+ * @param requestOptions - Per-call request options.
41521
+ * @returns The upload: queued or resumed (HTTP 202), or unchanged (HTTP 200)
41522
+ * when the import is already complete or already has a live worker.
41523
+ * @throws {BadRequestError} 400 when bytes are still missing.
41524
+ * @throws {ForbiddenError} 403 when the caller did not open the upload.
41525
+ * @throws {NotFoundError} 404 when the tenant has no RDF upload with this id.
41526
+ * @throws {ConstraintViolationError} 409 while a paused worker is still
41527
+ * finishing its pause; retry the call.
41528
+ *
41529
+ * @remarks
41530
+ * The import runs in the background and commits in durable batches; a
41531
+ * resumed import continues from the last committed batch. Follow it with
41532
+ * {@link IngestionClient.getRdfUpload}. Response is snake_case on the wire.
41533
+ *
41534
+ * @example
41535
+ * ```typescript
41536
+ * const started = await client.ingestion.completeRdfUpload(id);
41537
+ * console.log(started.status); // 'queued'
41538
+ * ```
41539
+ */
41540
+ async completeRdfUpload(id, requestOptions) {
41541
+ const response = await this.api.complete(id, toRequestParams(requestOptions));
41542
+ return decodeResponse(response, RdfUploadFromApiToFront);
41543
+ }
41544
+ /**
41545
+ * Pause a running RDF import at its next durable checkpoint —
41546
+ * `POST /api/v1/ingest/rdf/uploads/{id}/pause`.
41547
+ *
41548
+ * @param id - The upload id ({@link RdfUpload.id}).
41549
+ * @param requestOptions - Per-call request options.
41550
+ * @returns The receipt, with `status: 'pausing'`.
41551
+ * @throws {BadRequestError} 400 when the import is not `queued` or
41552
+ * `processing`.
41553
+ * @throws {ForbiddenError} 403 when the caller did not open the upload.
41554
+ * @throws {NotFoundError} 404 when the tenant has no RDF upload with this id.
41555
+ *
41556
+ * @remarks
41557
+ * The import stops after its current batch commits; the upload then reads
41558
+ * `paused`. {@link IngestionClient.completeRdfUpload} resumes it. Response
41559
+ * is snake_case on the wire.
41560
+ *
41561
+ * @example
41562
+ * ```typescript
41563
+ * await client.ingestion.pauseRdfUpload(id);
41564
+ * // later
41565
+ * await client.ingestion.completeRdfUpload(id);
41566
+ * ```
41567
+ */
41568
+ async pauseRdfUpload(id, requestOptions) {
41569
+ const response = await this.api.pause(id, toRequestParams(requestOptions));
41570
+ return decodeResponse(response, RdfUploadPauseReceiptFromApiToFront);
41571
+ }
41286
41572
  };
41287
41573
 
41288
41574
  // src/normalizers/reviews.ts
@@ -53851,6 +54137,20 @@ function OsfqlFailureFromApiToFront(body) {
53851
54137
  }
53852
54138
  return failure;
53853
54139
  }
54140
+ function OsfqlTokenFromApiToFront(dto) {
54141
+ return {
54142
+ line: dto.line,
54143
+ startChar: dto.start_char,
54144
+ length: dto.length,
54145
+ kind: dto.kind
54146
+ };
54147
+ }
54148
+ function OsfqlTokensResponseFromApiToFront(dto) {
54149
+ return {
54150
+ encoding: dto.encoding,
54151
+ tokens: dto.tokens.map(OsfqlTokenFromApiToFront)
54152
+ };
54153
+ }
53854
54154
 
53855
54155
  // src/resources/osfql.ts
53856
54156
  var OsfqlClient = class {
@@ -54194,6 +54494,38 @@ var OsfqlClient = class {
54194
54494
  });
54195
54495
  return decodeResponse(response, (dto) => dto.map(OsfqlCatalogEntryFromApiToFront));
54196
54496
  }
54497
+ /**
54498
+ * Highlight OSFQL source with the engine's own classifier — the one the
54499
+ * OSFQL language server uses.
54500
+ *
54501
+ * @param query - The source as authored, incomplete statements included. At
54502
+ * most 256 KiB of UTF-8.
54503
+ * @param requestOptions - Per-call transport options (timeout, signal, headers).
54504
+ * @returns The editor tokens, sorted by position, in UTF-16 coordinates.
54505
+ * @throws {BadRequestError} 400 when the source exceeds 256 KiB.
54506
+ *
54507
+ * @remarks
54508
+ * Sent to `POST /api/v1/osfql/tokens` as `{ "query": … }`; the response is
54509
+ * mapped from snake_case (`start_char`) at the boundary. The engine parser
54510
+ * classifies sorts, features, literals and required fields, with a lexical
54511
+ * fallback for an incomplete document. Nothing runs and the knowledge base
54512
+ * is not read. This is presentation data, not validation: a source with
54513
+ * errors still receives tokens. Use {@link OsfqlClient.diagnose} for errors.
54514
+ *
54515
+ * @example
54516
+ * ```typescript
54517
+ * const source = 'MATCH person(name: ?N);';
54518
+ * const { tokens } = await client.osfql.tokens(source);
54519
+ * for (const t of tokens) {
54520
+ * const text = source.split('\n')[t.line]?.slice(t.startChar, t.startChar + t.length);
54521
+ * console.log(t.kind, text); // "keyword MATCH", "sort person", …
54522
+ * }
54523
+ * ```
54524
+ */
54525
+ async tokens(query, requestOptions) {
54526
+ const response = await this.api.osfqlTokens({ query }, toRequestParams(requestOptions));
54527
+ return decodeResponse(response, OsfqlTokensResponseFromApiToFront);
54528
+ }
54197
54529
  };
54198
54530
  function rethrowOsfqlFailure(error) {
54199
54531
  if (error instanceof ApiError) {