@naturali/cli 0.71.2 → 0.73.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 (2) hide show
  1. package/dist/index.mjs +2065 -443
  2. package/package.json +2 -2
package/dist/index.mjs CHANGED
@@ -14,9 +14,23 @@ var __exportAll = (all, no_symbols) => {
14
14
  };
15
15
  //#endregion
16
16
  //#region package.json
17
- var version = "0.71.2";
17
+ var version = "0.73.0";
18
18
  //#endregion
19
19
  //#region ../sdk/src/generated/core/bodySerializer.gen.ts
20
+ const serializeFormDataPair = (data, key, value) => {
21
+ if (typeof value === "string" || value instanceof Blob) data.append(key, value);
22
+ else if (value instanceof Date) data.append(key, value.toISOString());
23
+ else data.append(key, JSON.stringify(value));
24
+ };
25
+ const formDataBodySerializer = { bodySerializer: (body) => {
26
+ const data = new FormData();
27
+ Object.entries(body).forEach(([key, value]) => {
28
+ if (value === void 0 || value === null) return;
29
+ if (Array.isArray(value)) value.forEach((v) => serializeFormDataPair(data, key, v));
30
+ else serializeFormDataPair(data, key, value);
31
+ });
32
+ return data;
33
+ } };
20
34
  const jsonBodySerializer = { bodySerializer: (body) => JSON.stringify(body, (_key, value) => typeof value === "bigint" ? value.toString() : value) };
21
35
  //#endregion
22
36
  //#region ../sdk/src/generated/core/serverSentEvents.gen.ts
@@ -1677,6 +1691,196 @@ var Conversations = class {
1677
1691
  });
1678
1692
  }
1679
1693
  };
1694
+ var Documents = class {
1695
+ /**
1696
+ * List documents
1697
+ *
1698
+ * Returns all documents the caller has access to. If projectId is provided, returns only documents in that project. project keys are scoped to a single project automatically. JWT users without projectId receive documents across all their accessible projects.
1699
+ */
1700
+ static listDocuments(options) {
1701
+ return (options.client ?? client).get({
1702
+ url: "/v1/projects/{project_id}/documents",
1703
+ ...options
1704
+ });
1705
+ }
1706
+ /**
1707
+ * Create a document
1708
+ *
1709
+ * Creates a new text document and generates an embedding vector for semantic search. project keys automatically infer the project from the key's scope; JWT callers must supply projectId.
1710
+ */
1711
+ static createDocument(options) {
1712
+ return (options.client ?? client).post({
1713
+ url: "/v1/projects/{project_id}/documents",
1714
+ ...options,
1715
+ headers: {
1716
+ "Content-Type": "application/json",
1717
+ ...options.headers
1718
+ }
1719
+ });
1720
+ }
1721
+ /**
1722
+ * Ingest a file into a chunked document
1723
+ *
1724
+ * Parses an already-uploaded file and creates one Document split into one or
1725
+ * more embedded chunks. The source format is detected from the file's content
1726
+ * type: PDFs are parsed page-by-page; `text/plain` and `text/markdown` files
1727
+ * are read as a single source. How the source is chunked is controlled by
1728
+ * `chunk_strategy`.
1729
+ *
1730
+ * A file can only back one Document — a second call with the same `file_id`
1731
+ * returns `409 FILE_ALREADY_INGESTED`. To re-process an already-ingested file
1732
+ * (e.g. with a different `chunk_strategy`), use
1733
+ * `POST /documents/{document_id}/ingest`; to ingest the same source under a
1734
+ * different path, upload a new copy of the file first.
1735
+ *
1736
+ */
1737
+ static ingestDocument(options) {
1738
+ return (options.client ?? client).post({
1739
+ url: "/v1/projects/{project_id}/documents/ingest",
1740
+ ...options,
1741
+ headers: {
1742
+ "Content-Type": "application/json",
1743
+ ...options.headers
1744
+ }
1745
+ });
1746
+ }
1747
+ /**
1748
+ * Delete a document
1749
+ *
1750
+ * Deletes a document and its underlying file
1751
+ */
1752
+ static deleteDocument(options) {
1753
+ return (options.client ?? client).delete({
1754
+ url: "/v1/projects/{project_id}/documents/{document_id}",
1755
+ ...options
1756
+ });
1757
+ }
1758
+ /**
1759
+ * Get a document by ID
1760
+ *
1761
+ * Returns a document with its text content
1762
+ */
1763
+ static getDocument(options) {
1764
+ return (options.client ?? client).get({
1765
+ url: "/v1/projects/{project_id}/documents/{document_id}",
1766
+ ...options
1767
+ });
1768
+ }
1769
+ /**
1770
+ * Update a document
1771
+ *
1772
+ * Updates document content, title, path, metadata, or tags. Supplying `path` moves the document to a new logical path within the project.
1773
+ */
1774
+ static updateDocument(options) {
1775
+ return (options.client ?? client).patch({
1776
+ url: "/v1/projects/{project_id}/documents/{document_id}",
1777
+ ...options,
1778
+ headers: {
1779
+ "Content-Type": "application/json",
1780
+ ...options.headers
1781
+ }
1782
+ });
1783
+ }
1784
+ /**
1785
+ * Get document ingestion status
1786
+ *
1787
+ * Returns a lightweight ingestion status payload for polling — `status`,
1788
+ * `chunk_count`, `total_pages`, and (when failed) `error`. Unlike
1789
+ * `GET /documents/{document_id}`, it never returns the assembled chunk
1790
+ * content, so it is cheap to poll on large documents. A document whose
1791
+ * ingestion has stalled (no progress past the configured timeout) is
1792
+ * transitioned to `failed` with `error=INGESTION_TIMEOUT` on read.
1793
+ *
1794
+ */
1795
+ static getDocumentStatus(options) {
1796
+ return (options.client ?? client).get({
1797
+ url: "/v1/projects/{project_id}/documents/{document_id}/status",
1798
+ ...options
1799
+ });
1800
+ }
1801
+ /**
1802
+ * Re-ingest an existing document
1803
+ *
1804
+ * Re-runs ingestion for an existing document against its already-stored
1805
+ * source file. Existing chunks are discarded and the document is reset to
1806
+ * `status=pending` before re-processing. Use this to recover a document
1807
+ * stuck in `processing`/`failed` or to re-chunk with a different strategy
1808
+ * without re-uploading the file. Background by default (`202`); pass
1809
+ * `?wait=true` to run synchronously (`201`).
1810
+ *
1811
+ */
1812
+ static reingestDocument(options) {
1813
+ return (options.client ?? client).post({
1814
+ url: "/v1/projects/{project_id}/documents/{document_id}/ingest",
1815
+ ...options,
1816
+ headers: {
1817
+ "Content-Type": "application/json",
1818
+ ...options.headers
1819
+ }
1820
+ });
1821
+ }
1822
+ /**
1823
+ * Get document tags
1824
+ *
1825
+ * Returns all tags attached to the document
1826
+ */
1827
+ static getDocumentTags(options) {
1828
+ return (options.client ?? client).get({
1829
+ url: "/v1/projects/{project_id}/documents/{document_id}/tags",
1830
+ ...options
1831
+ });
1832
+ }
1833
+ /**
1834
+ * Merge document tags
1835
+ *
1836
+ * Merges provided tags with existing tags (existing tags are preserved unless overridden)
1837
+ */
1838
+ static mergeDocumentTags(options) {
1839
+ return (options.client ?? client).patch({
1840
+ url: "/v1/projects/{project_id}/documents/{document_id}/tags",
1841
+ ...options,
1842
+ headers: {
1843
+ "Content-Type": "application/json",
1844
+ ...options.headers
1845
+ }
1846
+ });
1847
+ }
1848
+ /**
1849
+ * Replace document tags
1850
+ *
1851
+ * Replaces all tags on the document with the provided tags (not merged)
1852
+ */
1853
+ static replaceDocumentTags(options) {
1854
+ return (options.client ?? client).put({
1855
+ url: "/v1/projects/{project_id}/documents/{document_id}/tags",
1856
+ ...options,
1857
+ headers: {
1858
+ "Content-Type": "application/json",
1859
+ ...options.headers
1860
+ }
1861
+ });
1862
+ }
1863
+ };
1864
+ var Embeddings = class {
1865
+ /**
1866
+ * Create embeddings
1867
+ *
1868
+ * Generates embedding vectors for one or more text inputs using the server's configured embedding model.
1869
+ * Provide `input` for a single text or `inputs` for a batch. At least one is required.
1870
+ * Returns `embedding` when `input` is used, and `embeddings` when `inputs` is used.
1871
+ *
1872
+ */
1873
+ static createEmbeddings(options) {
1874
+ return (options.client ?? client).post({
1875
+ url: "/v1/projects/{project_id}/embeddings",
1876
+ ...options,
1877
+ headers: {
1878
+ "Content-Type": "application/json",
1879
+ ...options.headers
1880
+ }
1881
+ });
1882
+ }
1883
+ };
1680
1884
  var Evaluations = class {
1681
1885
  /**
1682
1886
  * List datasets
@@ -1953,6 +2157,165 @@ var Evaluations = class {
1953
2157
  });
1954
2158
  }
1955
2159
  };
2160
+ var Files = class {
2161
+ /**
2162
+ * List all files
2163
+ *
2164
+ * Returns a list of all stored files
2165
+ */
2166
+ static listFiles(options) {
2167
+ return (options.client ?? client).get({
2168
+ url: "/v1/projects/{project_id}/files",
2169
+ ...options
2170
+ });
2171
+ }
2172
+ /**
2173
+ * Create a file
2174
+ *
2175
+ * Creates a new file record in the system
2176
+ */
2177
+ static createFile(options) {
2178
+ return (options.client ?? client).post({
2179
+ url: "/v1/projects/{project_id}/files",
2180
+ ...options,
2181
+ headers: {
2182
+ "Content-Type": "application/json",
2183
+ ...options.headers
2184
+ }
2185
+ });
2186
+ }
2187
+ /**
2188
+ * Upload a file
2189
+ *
2190
+ * Uploads a file to the server and stores it in the configured storage directory
2191
+ */
2192
+ static uploadFile(options) {
2193
+ return (options.client ?? client).post({
2194
+ ...formDataBodySerializer,
2195
+ url: "/v1/projects/{project_id}/files/upload",
2196
+ ...options,
2197
+ headers: {
2198
+ "Content-Type": null,
2199
+ ...options.headers
2200
+ }
2201
+ });
2202
+ }
2203
+ /**
2204
+ * Upload a file using base64 encoding
2205
+ *
2206
+ * Uploads a file to the server using base64-encoded content
2207
+ */
2208
+ static uploadFileBase64(options) {
2209
+ return (options.client ?? client).post({
2210
+ url: "/v1/projects/{project_id}/files/upload/base64",
2211
+ ...options,
2212
+ headers: {
2213
+ "Content-Type": "application/json",
2214
+ ...options.headers
2215
+ }
2216
+ });
2217
+ }
2218
+ /**
2219
+ * Delete a file
2220
+ *
2221
+ * Removes a file from the system by ID
2222
+ */
2223
+ static deleteFile(options) {
2224
+ return (options.client ?? client).delete({
2225
+ url: "/v1/projects/{project_id}/files/{file_id}",
2226
+ ...options
2227
+ });
2228
+ }
2229
+ /**
2230
+ * Get a file by ID
2231
+ *
2232
+ * Returns the data and metadata of a specific file
2233
+ */
2234
+ static getFile(options) {
2235
+ return (options.client ?? client).get({
2236
+ url: "/v1/projects/{project_id}/files/{file_id}",
2237
+ ...options
2238
+ });
2239
+ }
2240
+ /**
2241
+ * Download a file
2242
+ *
2243
+ * Streams the file content to the client
2244
+ */
2245
+ static downloadFile(options) {
2246
+ return (options.client ?? client).get({
2247
+ url: "/v1/projects/{project_id}/files/{file_id}/download",
2248
+ ...options
2249
+ });
2250
+ }
2251
+ /**
2252
+ * Update file metadata
2253
+ *
2254
+ * Updates the metadata field of a file
2255
+ */
2256
+ static updateFileMetadata(options) {
2257
+ return (options.client ?? client).patch({
2258
+ url: "/v1/projects/{project_id}/files/{file_id}/metadata",
2259
+ ...options,
2260
+ headers: {
2261
+ "Content-Type": "application/json",
2262
+ ...options.headers
2263
+ }
2264
+ });
2265
+ }
2266
+ /**
2267
+ * Download file as base64
2268
+ *
2269
+ * Returns the file content encoded as base64
2270
+ */
2271
+ static downloadFileBase64(options) {
2272
+ return (options.client ?? client).get({
2273
+ url: "/v1/projects/{project_id}/files/{file_id}/download/base64",
2274
+ ...options
2275
+ });
2276
+ }
2277
+ /**
2278
+ * Get file tags
2279
+ *
2280
+ * Returns all tags attached to the file
2281
+ */
2282
+ static getFileTags(options) {
2283
+ return (options.client ?? client).get({
2284
+ url: "/v1/projects/{project_id}/files/{file_id}/tags",
2285
+ ...options
2286
+ });
2287
+ }
2288
+ /**
2289
+ * Merge file tags
2290
+ *
2291
+ * Merges provided tags with existing tags
2292
+ */
2293
+ static mergeFileTags(options) {
2294
+ return (options.client ?? client).patch({
2295
+ url: "/v1/projects/{project_id}/files/{file_id}/tags",
2296
+ ...options,
2297
+ headers: {
2298
+ "Content-Type": "application/json",
2299
+ ...options.headers
2300
+ }
2301
+ });
2302
+ }
2303
+ /**
2304
+ * Replace file tags
2305
+ *
2306
+ * Replaces all tags on the file with the provided tags
2307
+ */
2308
+ static replaceFileTags(options) {
2309
+ return (options.client ?? client).put({
2310
+ url: "/v1/projects/{project_id}/files/{file_id}/tags",
2311
+ ...options,
2312
+ headers: {
2313
+ "Content-Type": "application/json",
2314
+ ...options.headers
2315
+ }
2316
+ });
2317
+ }
2318
+ };
1956
2319
  var Generations = class {
1957
2320
  /**
1958
2321
  * List generations
@@ -2029,26 +2392,26 @@ var Generations = class {
2029
2392
  });
2030
2393
  }
2031
2394
  };
2032
- var ModelRoutes = class {
2395
+ var IngestionRules = class {
2033
2396
  /**
2034
- * List model routes
2397
+ * List ingestion rules
2035
2398
  *
2036
- * Returns the model routes defined in a project
2399
+ * Returns the ingestion rules for a project
2037
2400
  */
2038
- static listModelRoutes(options) {
2401
+ static listIngestionRules(options) {
2039
2402
  return (options.client ?? client).get({
2040
- url: "/v1/projects/{project_id}/model-routes",
2403
+ url: "/v1/projects/{project_id}/ingestion-rules",
2041
2404
  ...options
2042
2405
  });
2043
2406
  }
2044
2407
  /**
2045
- * Create a model route
2408
+ * Create an ingestion rule
2046
2409
  *
2047
- * Creates a project-scoped model route: a named, ordered list of provider+model targets tried in array order. Every target must reference an AI provider in the same project (400 otherwise), and the total attempt budget — the sum of `1 + max_retries` over all targets — may not exceed 10 (400 naming the computed total). A duplicate `name` in the project is rejected with 409.
2410
+ * Creates a rule mapping a content_type glob to a converter. Exactly one of tool_id or agent_id must be set.
2048
2411
  */
2049
- static createModelRoute(options) {
2412
+ static createIngestionRule(options) {
2050
2413
  return (options.client ?? client).post({
2051
- url: "/v1/projects/{project_id}/model-routes",
2414
+ url: "/v1/projects/{project_id}/ingestion-rules",
2052
2415
  ...options,
2053
2416
  headers: {
2054
2417
  "Content-Type": "application/json",
@@ -2057,35 +2420,35 @@ var ModelRoutes = class {
2057
2420
  });
2058
2421
  }
2059
2422
  /**
2060
- * Delete a model route
2423
+ * Delete an ingestion rule
2061
2424
  *
2062
- * Deletes a model route. Returns 409 when an agent still references it — a routed agent has no pinned provider to fall back on, so the reference must be repointed or the agent deleted first.
2425
+ * Deletes an ingestion rule
2063
2426
  */
2064
- static deleteModelRoute(options) {
2427
+ static deleteIngestionRule(options) {
2065
2428
  return (options.client ?? client).delete({
2066
- url: "/v1/projects/{project_id}/model-routes/{route_id}",
2429
+ url: "/v1/projects/{project_id}/ingestion-rules/{ingestion_rule_id}",
2067
2430
  ...options
2068
2431
  });
2069
2432
  }
2070
2433
  /**
2071
- * Get a model route
2434
+ * Get an ingestion rule
2072
2435
  *
2073
- * Returns a specific model route
2436
+ * Returns a specific ingestion rule
2074
2437
  */
2075
- static getModelRoute(options) {
2438
+ static getIngestionRule(options) {
2076
2439
  return (options.client ?? client).get({
2077
- url: "/v1/projects/{project_id}/model-routes/{route_id}",
2440
+ url: "/v1/projects/{project_id}/ingestion-rules/{ingestion_rule_id}",
2078
2441
  ...options
2079
2442
  });
2080
2443
  }
2081
2444
  /**
2082
- * Update a model route
2445
+ * Update an ingestion rule
2083
2446
  *
2084
- * Updates a model route's name, targets, retry classes, or breaker configuration. Omitted fields are left unchanged.
2447
+ * Updates fields of an ingestion rule
2085
2448
  */
2086
- static updateModelRoute(options) {
2087
- return (options.client ?? client).put({
2088
- url: "/v1/projects/{project_id}/model-routes/{route_id}",
2449
+ static updateIngestionRule(options) {
2450
+ return (options.client ?? client).patch({
2451
+ url: "/v1/projects/{project_id}/ingestion-rules/{ingestion_rule_id}",
2089
2452
  ...options,
2090
2453
  headers: {
2091
2454
  "Content-Type": "application/json",
@@ -2094,9 +2457,91 @@ var ModelRoutes = class {
2094
2457
  });
2095
2458
  }
2096
2459
  };
2097
- var Models = class {
2460
+ var Knowledge = class {
2098
2461
  /**
2099
- * List models
2462
+ * Search knowledge
2463
+ *
2464
+ * Searches across documents and memory entries using semantic search, file paths, document IDs, or memory IDs/tags. At least one of `query`, `document_paths`, `document_ids`, `memory_ids`, or `memory_tags` must be provided.
2465
+ */
2466
+ static searchKnowledge(options) {
2467
+ return (options.client ?? client).post({
2468
+ url: "/v1/projects/{project_id}/knowledge/search",
2469
+ ...options,
2470
+ headers: {
2471
+ "Content-Type": "application/json",
2472
+ ...options.headers
2473
+ }
2474
+ });
2475
+ }
2476
+ };
2477
+ var ModelRoutes = class {
2478
+ /**
2479
+ * List model routes
2480
+ *
2481
+ * Returns the model routes defined in a project
2482
+ */
2483
+ static listModelRoutes(options) {
2484
+ return (options.client ?? client).get({
2485
+ url: "/v1/projects/{project_id}/model-routes",
2486
+ ...options
2487
+ });
2488
+ }
2489
+ /**
2490
+ * Create a model route
2491
+ *
2492
+ * Creates a project-scoped model route: a named, ordered list of provider+model targets tried in array order. Every target must reference an AI provider in the same project (400 otherwise), and the total attempt budget — the sum of `1 + max_retries` over all targets — may not exceed 10 (400 naming the computed total). A duplicate `name` in the project is rejected with 409.
2493
+ */
2494
+ static createModelRoute(options) {
2495
+ return (options.client ?? client).post({
2496
+ url: "/v1/projects/{project_id}/model-routes",
2497
+ ...options,
2498
+ headers: {
2499
+ "Content-Type": "application/json",
2500
+ ...options.headers
2501
+ }
2502
+ });
2503
+ }
2504
+ /**
2505
+ * Delete a model route
2506
+ *
2507
+ * Deletes a model route. Returns 409 when an agent still references it — a routed agent has no pinned provider to fall back on, so the reference must be repointed or the agent deleted first.
2508
+ */
2509
+ static deleteModelRoute(options) {
2510
+ return (options.client ?? client).delete({
2511
+ url: "/v1/projects/{project_id}/model-routes/{route_id}",
2512
+ ...options
2513
+ });
2514
+ }
2515
+ /**
2516
+ * Get a model route
2517
+ *
2518
+ * Returns a specific model route
2519
+ */
2520
+ static getModelRoute(options) {
2521
+ return (options.client ?? client).get({
2522
+ url: "/v1/projects/{project_id}/model-routes/{route_id}",
2523
+ ...options
2524
+ });
2525
+ }
2526
+ /**
2527
+ * Update a model route
2528
+ *
2529
+ * Updates a model route's name, targets, retry classes, or breaker configuration. Omitted fields are left unchanged.
2530
+ */
2531
+ static updateModelRoute(options) {
2532
+ return (options.client ?? client).put({
2533
+ url: "/v1/projects/{project_id}/model-routes/{route_id}",
2534
+ ...options,
2535
+ headers: {
2536
+ "Content-Type": "application/json",
2537
+ ...options.headers
2538
+ }
2539
+ });
2540
+ }
2541
+ };
2542
+ var Models = class {
2543
+ /**
2544
+ * List models
2100
2545
  *
2101
2546
  * Lists catalog models, sorted by id. Filter by vendor, provider, input/output modality, status, or `managed` — the last being the axis that decides whether a model is usable without bringing your own provider credentials, so `?managed=true&status=available` is the set a project's managed provider serves today.
2102
2547
  *
@@ -3361,8 +3806,13 @@ var NaturaliClient = class {
3361
3806
  channels;
3362
3807
  auth;
3363
3808
  conversations;
3809
+ documents;
3810
+ embeddings;
3364
3811
  evaluations;
3812
+ files;
3365
3813
  generations;
3814
+ ingestionRules;
3815
+ knowledge;
3366
3816
  modelRoutes;
3367
3817
  models;
3368
3818
  orchestrations;
@@ -3395,8 +3845,13 @@ var NaturaliClient = class {
3395
3845
  this.channels = bindResource(Channels, this.http);
3396
3846
  this.auth = bindResource(Auth, this.http);
3397
3847
  this.conversations = bindResource(Conversations, this.http);
3848
+ this.documents = bindResource(Documents, this.http);
3849
+ this.embeddings = bindResource(Embeddings, this.http);
3398
3850
  this.evaluations = bindResource(Evaluations, this.http);
3851
+ this.files = bindResource(Files, this.http);
3399
3852
  this.generations = bindResource(Generations, this.http);
3853
+ this.ingestionRules = bindResource(IngestionRules, this.http);
3854
+ this.knowledge = bindResource(Knowledge, this.http);
3400
3855
  this.modelRoutes = bindResource(ModelRoutes, this.http);
3401
3856
  this.models = bindResource(Models, this.http);
3402
3857
  this.orchestrations = bindResource(Orchestrations, this.http);
@@ -3424,8 +3879,13 @@ var src_exports = /* @__PURE__ */ __exportAll({
3424
3879
  Auth: () => Auth,
3425
3880
  Channels: () => Channels,
3426
3881
  Conversations: () => Conversations,
3882
+ Documents: () => Documents,
3883
+ Embeddings: () => Embeddings,
3427
3884
  Evaluations: () => Evaluations,
3885
+ Files: () => Files,
3428
3886
  Generations: () => Generations,
3887
+ IngestionRules: () => IngestionRules,
3888
+ Knowledge: () => Knowledge,
3429
3889
  ModelRoutes: () => ModelRoutes,
3430
3890
  Models: () => Models,
3431
3891
  NaturaliClient: () => NaturaliClient,
@@ -6988,14 +7448,18 @@ const routes = {
6988
7448
  "in": "path"
6989
7449
  }]
6990
7450
  },
6991
- "list-datasets": {
6992
- serviceClass: "Evaluations",
6993
- operationId: "listDatasets",
6994
- description: "Returns the datasets defined in a project",
6995
- moduleDocsUrl: "https://docs.naturali.ai/docs/modules/evaluations",
7451
+ "list-documents": {
7452
+ serviceClass: "Documents",
7453
+ operationId: "listDocuments",
7454
+ description: "Returns all documents the caller has access to. If projectId is provided, returns only documents in that project. project keys are scoped to a single project automatically. JWT users without projectId receive documents across all their accessible projects.",
7455
+ moduleDocsUrl: "https://docs.naturali.ai/docs/modules/documents",
6996
7456
  httpMethod: "get",
6997
7457
  pathParams: ["project_id"],
6998
- queryParams: ["limit", "offset"],
7458
+ queryParams: [
7459
+ "path_prefix",
7460
+ "limit",
7461
+ "offset"
7462
+ ],
6999
7463
  flags: [
7000
7464
  {
7001
7465
  "name": "project_id",
@@ -7004,6 +7468,13 @@ const routes = {
7004
7468
  "type": "string",
7005
7469
  "in": "path"
7006
7470
  },
7471
+ {
7472
+ "name": "path_prefix",
7473
+ "description": "Only documents filed under this directory. The prefix is a path boundary, not a substring: `/reports` returns `/reports/q1.txt` and never `/reports-archive/q1.txt`, and `/` selects the whole project. A leading slash is optional and a trailing one is ignored, so `reports`, `/reports` and `/reports/` are the same filter. `%` and `_` are literal characters, not wildcards.",
7474
+ "required": false,
7475
+ "type": "string",
7476
+ "in": "query"
7477
+ },
7007
7478
  {
7008
7479
  "name": "limit",
7009
7480
  "description": "Maximum number of results to return",
@@ -7020,11 +7491,11 @@ const routes = {
7020
7491
  }
7021
7492
  ]
7022
7493
  },
7023
- "create-dataset": {
7024
- serviceClass: "Evaluations",
7025
- operationId: "createDataset",
7026
- description: "Creates a project-scoped dataset a named collection of test cases an eval runs an agent against. Names are unique per project. Datasets are operator-owned **fixtures**. The platform's content purge never deletes or mutates a dataset item, so erasing a generation cannot silently stop a test suite from being runnable.",
7027
- moduleDocsUrl: "https://docs.naturali.ai/docs/modules/evaluations",
7494
+ "create-document": {
7495
+ serviceClass: "Documents",
7496
+ operationId: "createDocument",
7497
+ description: "Creates a new text document and generates an embedding vector for semantic search. project keys automatically infer the project from the key's scope; JWT callers must supply projectId.",
7498
+ moduleDocsUrl: "https://docs.naturali.ai/docs/modules/documents",
7028
7499
  httpMethod: "post",
7029
7500
  pathParams: ["project_id"],
7030
7501
  queryParams: [],
@@ -7037,51 +7508,78 @@ const routes = {
7037
7508
  "in": "path"
7038
7509
  },
7039
7510
  {
7040
- "name": "name",
7041
- "description": "Unique name within the project",
7511
+ "name": "content",
7512
+ "description": "",
7042
7513
  "required": true,
7043
7514
  "type": "string",
7044
7515
  "in": "body"
7045
7516
  },
7046
7517
  {
7047
- "name": "description",
7048
- "description": "What this suite covers",
7518
+ "name": "path",
7519
+ "description": "Logical path within the project (e.g. /reports/q1.txt). Defaults to /filename if omitted.",
7520
+ "required": false,
7521
+ "type": "string",
7522
+ "in": "body"
7523
+ },
7524
+ {
7525
+ "name": "filename",
7526
+ "description": "",
7527
+ "required": false,
7528
+ "type": "string",
7529
+ "in": "body"
7530
+ },
7531
+ {
7532
+ "name": "title",
7533
+ "description": "Document title",
7534
+ "required": false,
7535
+ "type": "string",
7536
+ "in": "body"
7537
+ },
7538
+ {
7539
+ "name": "metadata",
7540
+ "description": "Arbitrary metadata object. Unlike other body fields, keys are stored and returned verbatim in the casing supplied — they are not converted between snake_case and camelCase.",
7541
+ "required": false,
7542
+ "type": "object",
7543
+ "in": "body"
7544
+ },
7545
+ {
7546
+ "name": "tags",
7547
+ "description": "Key-value tags",
7548
+ "required": false,
7549
+ "type": "object",
7550
+ "in": "body"
7551
+ },
7552
+ {
7553
+ "name": "chunk_strategy",
7554
+ "description": "How to split the content into embeddable chunks. `whole` (default) stores the content as a single chunk; `size` splits into fixed-size character windows with overlap. `page` is equivalent to `whole` for plain text.",
7049
7555
  "required": false,
7050
7556
  "type": "string",
7051
7557
  "in": "body"
7558
+ },
7559
+ {
7560
+ "name": "chunk_size",
7561
+ "description": "Window size in characters when `chunk_strategy=size`. Defaults to 1000.",
7562
+ "required": false,
7563
+ "type": "integer",
7564
+ "in": "body"
7565
+ },
7566
+ {
7567
+ "name": "chunk_overlap",
7568
+ "description": "Overlap in characters between consecutive windows when `chunk_strategy=size`. Defaults to 200.",
7569
+ "required": false,
7570
+ "type": "integer",
7571
+ "in": "body"
7052
7572
  }
7053
7573
  ]
7054
7574
  },
7055
- "get-dataset": {
7056
- serviceClass: "Evaluations",
7057
- operationId: "getDataset",
7058
- description: "Returns a specific dataset",
7059
- moduleDocsUrl: "https://docs.naturali.ai/docs/modules/evaluations",
7060
- httpMethod: "get",
7061
- pathParams: ["project_id", "dataset_id"],
7062
- queryParams: [],
7063
- flags: [{
7064
- "name": "project_id",
7065
- "description": "Project public ID (proj_ prefix).",
7066
- "required": true,
7067
- "type": "string",
7068
- "in": "path"
7069
- }, {
7070
- "name": "dataset_id",
7071
- "description": "Dataset ID",
7072
- "required": true,
7073
- "type": "string",
7074
- "in": "path"
7075
- }]
7076
- },
7077
- "update-dataset": {
7078
- serviceClass: "Evaluations",
7079
- operationId: "updateDataset",
7080
- description: "Updates a dataset's name and/or description",
7081
- moduleDocsUrl: "https://docs.naturali.ai/docs/modules/evaluations",
7082
- httpMethod: "put",
7083
- pathParams: ["project_id", "dataset_id"],
7084
- queryParams: [],
7575
+ "ingest-document": {
7576
+ serviceClass: "Documents",
7577
+ operationId: "ingestDocument",
7578
+ description: "Parses an already-uploaded file and creates one Document split into one or more embedded chunks. The source format is detected from the file's content type: PDFs are parsed page-by-page; `text/plain` and `text/markdown` files are read as a single source. How the source is chunked is controlled by `chunk_strategy`. A file can only back one Document — a second call with the same `file_id` returns `409 FILE_ALREADY_INGESTED`. To re-process an already-ingested file (e.g. with a different `chunk_strategy`), use `POST /documents/{document_id}/ingest`; to ingest the same source under a different path, upload a new copy of the file first.",
7579
+ moduleDocsUrl: "https://docs.naturali.ai/docs/modules/documents",
7580
+ httpMethod: "post",
7581
+ pathParams: ["project_id"],
7582
+ queryParams: ["wait"],
7085
7583
  flags: [
7086
7584
  {
7087
7585
  "name": "project_id",
@@ -7091,35 +7589,63 @@ const routes = {
7091
7589
  "in": "path"
7092
7590
  },
7093
7591
  {
7094
- "name": "dataset_id",
7095
- "description": "Dataset ID",
7592
+ "name": "wait",
7593
+ "description": "When omitted or `false` (default), processing runs in the background and `202 Accepted` is returned immediately with `status=pending`. Pass `true` to block until processing completes and receive `201 Created` with `status=ready`.",
7594
+ "required": false,
7595
+ "type": "boolean",
7596
+ "in": "query"
7597
+ },
7598
+ {
7599
+ "name": "file_id",
7600
+ "description": "ID of the uploaded file. Must be one of application/pdf, text/plain, text/markdown.",
7096
7601
  "required": true,
7097
7602
  "type": "string",
7098
- "in": "path"
7603
+ "in": "body"
7099
7604
  },
7100
7605
  {
7101
- "name": "name",
7102
- "description": "",
7606
+ "name": "path_prefix",
7607
+ "description": "Path prefix under which to store the document (e.g. /docs/). The filename is appended automatically.",
7103
7608
  "required": false,
7104
7609
  "type": "string",
7105
7610
  "in": "body"
7106
7611
  },
7107
7612
  {
7108
- "name": "description",
7109
- "description": "",
7613
+ "name": "tags",
7614
+ "description": "Key-value tags to attach to the document.",
7615
+ "required": false,
7616
+ "type": "object",
7617
+ "in": "body"
7618
+ },
7619
+ {
7620
+ "name": "chunk_strategy",
7621
+ "description": "How to split the source into chunks. `page` (default) creates one chunk per non-empty page (PDF); for non-paged sources it yields a single chunk. `whole` joins everything into one chunk. `size` splits into fixed-size character windows with overlap.",
7110
7622
  "required": false,
7111
7623
  "type": "string",
7112
7624
  "in": "body"
7625
+ },
7626
+ {
7627
+ "name": "chunk_size",
7628
+ "description": "Window size in characters when `chunk_strategy=size`. Defaults to 1000.",
7629
+ "required": false,
7630
+ "type": "integer",
7631
+ "in": "body"
7632
+ },
7633
+ {
7634
+ "name": "chunk_overlap",
7635
+ "description": "Overlap in characters between consecutive windows when `chunk_strategy=size`. Defaults to 200.",
7636
+ "required": false,
7637
+ "type": "integer",
7638
+ "in": "body"
7113
7639
  }
7114
7640
  ]
7115
7641
  },
7116
- "delete-dataset": {
7117
- serviceClass: "Evaluations",
7118
- operationId: "deleteDataset",
7119
- description: "Deletes a dataset, its items, and every eval bound to it. Results of runs that already scored those items keep their frozen copies of the input and expected output.",
7120
- moduleDocsUrl: "https://docs.naturali.ai/docs/modules/evaluations",
7121
- httpMethod: "delete",
7122
- pathParams: ["project_id", "dataset_id"],
7642
+ "get-document": {
7643
+ serviceClass: "Documents",
7644
+ operationId: "getDocument",
7645
+ description: "Returns a document with its text content",
7646
+ moduleDocsUrl: "https://docs.naturali.ai/docs/modules/documents",
7647
+ httpMethod: "get",
7648
+ pathParams: ["project_id", "document_id"],
7123
7649
  queryParams: [],
7124
7650
  flags: [{
7125
7651
  "name": "project_id",
@@ -7128,21 +7654,21 @@ const routes = {
7128
7654
  "type": "string",
7129
7655
  "in": "path"
7130
7656
  }, {
7131
- "name": "dataset_id",
7132
- "description": "Dataset ID",
7657
+ "name": "document_id",
7658
+ "description": "Document ID",
7133
7659
  "required": true,
7134
7660
  "type": "string",
7135
7661
  "in": "path"
7136
7662
  }]
7137
7663
  },
7138
- "list-dataset-items": {
7139
- serviceClass: "Evaluations",
7140
- operationId: "listDatasetItems",
7141
- description: "Returns the test cases in a dataset, oldest first",
7142
- moduleDocsUrl: "https://docs.naturali.ai/docs/modules/evaluations",
7143
- httpMethod: "get",
7144
- pathParams: ["project_id", "dataset_id"],
7145
- queryParams: ["limit", "offset"],
7664
+ "update-document": {
7665
+ serviceClass: "Documents",
7666
+ operationId: "updateDocument",
7667
+ description: "Updates document content, title, path, metadata, or tags. Supplying `path` moves the document to a new logical path within the project.",
7668
+ moduleDocsUrl: "https://docs.naturali.ai/docs/modules/documents",
7669
+ httpMethod: "patch",
7670
+ pathParams: ["project_id", "document_id"],
7671
+ queryParams: [],
7146
7672
  flags: [
7147
7673
  {
7148
7674
  "name": "project_id",
@@ -7152,82 +7678,101 @@ const routes = {
7152
7678
  "in": "path"
7153
7679
  },
7154
7680
  {
7155
- "name": "dataset_id",
7156
- "description": "Dataset ID",
7681
+ "name": "document_id",
7682
+ "description": "Document ID",
7157
7683
  "required": true,
7158
7684
  "type": "string",
7159
7685
  "in": "path"
7160
7686
  },
7161
7687
  {
7162
- "name": "limit",
7163
- "description": "Maximum number of results to return",
7688
+ "name": "content",
7689
+ "description": "New text content",
7164
7690
  "required": false,
7165
- "type": "integer",
7166
- "in": "query"
7691
+ "type": "string",
7692
+ "in": "body"
7167
7693
  },
7168
7694
  {
7169
- "name": "offset",
7170
- "description": "Number of results to skip",
7695
+ "name": "title",
7696
+ "description": "New title",
7171
7697
  "required": false,
7172
- "type": "integer",
7173
- "in": "query"
7174
- }
7175
- ]
7176
- },
7177
- "create-dataset-item": {
7178
- serviceClass: "Evaluations",
7179
- operationId: "createDatasetItem",
7180
- description: "Adds one test case. `input` is replayed verbatim as the generation's messages, so it must be a non-empty array of `{ role, content }`.",
7181
- moduleDocsUrl: "https://docs.naturali.ai/docs/modules/evaluations",
7182
- httpMethod: "post",
7183
- pathParams: ["project_id", "dataset_id"],
7184
- queryParams: [],
7185
- flags: [
7698
+ "type": "string",
7699
+ "in": "body"
7700
+ },
7186
7701
  {
7187
- "name": "project_id",
7188
- "description": "Project public ID (proj_ prefix).",
7189
- "required": true,
7190
- "type": "string",
7191
- "in": "path"
7192
- },
7193
- {
7194
- "name": "dataset_id",
7195
- "description": "Dataset ID",
7196
- "required": true,
7702
+ "name": "path",
7703
+ "description": "Logical path within the project (e.g. /reports/q1.txt). Pass null to clear.",
7704
+ "required": false,
7197
7705
  "type": "string",
7198
- "in": "path"
7199
- },
7200
- {
7201
- "name": "input",
7202
- "description": "Messages replayed verbatim as the generation's input",
7203
- "required": true,
7204
- "type": "array",
7205
7706
  "in": "body"
7206
7707
  },
7207
7708
  {
7208
- "name": "expected_output",
7209
- "description": "Reference answer for exact_match / embedding_similarity / llm_judge scorers",
7709
+ "name": "metadata",
7710
+ "description": "Arbitrary metadata object. Unlike other body fields, keys are stored and returned verbatim in the casing supplied — they are not converted between snake_case and camelCase.",
7210
7711
  "required": false,
7211
- "type": "string",
7712
+ "type": "object",
7212
7713
  "in": "body"
7213
7714
  },
7214
7715
  {
7215
- "name": "metadata",
7216
- "description": "Free-form tags, opaque to the platform",
7716
+ "name": "tags",
7717
+ "description": "Key-value tags",
7217
7718
  "required": false,
7218
7719
  "type": "object",
7219
7720
  "in": "body"
7220
7721
  }
7221
7722
  ]
7222
7723
  },
7223
- "create-dataset-item-from-generation": {
7224
- serviceClass: "Evaluations",
7225
- operationId: "createDatasetItemFromGeneration",
7226
- description: "Promotes a real, completed generation into a test case: its input messages become the item's `input`, and its own answer becomes `expected_output` unless you supply one. Use it to build an evaluation set out of production traffic rather than hand-authoring fixtures. The item is a **copy**, not a view. It keeps working after the source generation's content is purged, and `source_generation_id` goes null if that generation is deleted — a purge can never quietly stop a suite from being runnable. Requires both `evaluations:CreateDataset` and `generations:GetGeneration`: the call copies content out of a generation, so a principal that may not read that generation may not curate it either. Only a **completed** generation can be promoted (`409 GENERATION_NOT_COMPLETED`), and only while its content is still available: an agent or project running with `trace_content_mode: none` never stored the input, and a purged or expired generation no longer has it (`409 GENERATION_CONTENT_UNAVAILABLE`). Generations that predate input recording answer the same way.",
7227
- moduleDocsUrl: "https://docs.naturali.ai/docs/modules/evaluations",
7228
- httpMethod: "post",
7229
- pathParams: ["project_id", "dataset_id"],
7724
+ "delete-document": {
7725
+ serviceClass: "Documents",
7726
+ operationId: "deleteDocument",
7727
+ description: "Deletes a document and its underlying file",
7728
+ moduleDocsUrl: "https://docs.naturali.ai/docs/modules/documents",
7729
+ httpMethod: "delete",
7730
+ pathParams: ["project_id", "document_id"],
7731
+ queryParams: [],
7732
+ flags: [{
7733
+ "name": "project_id",
7734
+ "description": "Project public ID (proj_ prefix).",
7735
+ "required": true,
7736
+ "type": "string",
7737
+ "in": "path"
7738
+ }, {
7739
+ "name": "document_id",
7740
+ "description": "Document ID",
7741
+ "required": true,
7742
+ "type": "string",
7743
+ "in": "path"
7744
+ }]
7745
+ },
7746
+ "get-document-status": {
7747
+ serviceClass: "Documents",
7748
+ operationId: "getDocumentStatus",
7749
+ description: "Returns a lightweight ingestion status payload for polling — `status`, `chunk_count`, `total_pages`, and (when failed) `error`. Unlike `GET /documents/{document_id}`, it never returns the assembled chunk content, so it is cheap to poll on large documents. A document whose ingestion has stalled (no progress past the configured timeout) is transitioned to `failed` with `error=INGESTION_TIMEOUT` on read.",
7750
+ moduleDocsUrl: "https://docs.naturali.ai/docs/modules/documents",
7751
+ httpMethod: "get",
7752
+ pathParams: ["project_id", "document_id"],
7230
7753
  queryParams: [],
7754
+ flags: [{
7755
+ "name": "project_id",
7756
+ "description": "Project public ID (proj_ prefix).",
7757
+ "required": true,
7758
+ "type": "string",
7759
+ "in": "path"
7760
+ }, {
7761
+ "name": "document_id",
7762
+ "description": "Document ID",
7763
+ "required": true,
7764
+ "type": "string",
7765
+ "in": "path"
7766
+ }]
7767
+ },
7768
+ "reingest-document": {
7769
+ serviceClass: "Documents",
7770
+ operationId: "reingestDocument",
7771
+ description: "Re-runs ingestion for an existing document against its already-stored source file. Existing chunks are discarded and the document is reset to `status=pending` before re-processing. Use this to recover a document stuck in `processing`/`failed` or to re-chunk with a different strategy without re-uploading the file. Background by default (`202`); pass `?wait=true` to run synchronously (`201`).",
7772
+ moduleDocsUrl: "https://docs.naturali.ai/docs/modules/documents",
7773
+ httpMethod: "post",
7774
+ pathParams: ["project_id", "document_id"],
7775
+ queryParams: ["wait"],
7231
7776
  flags: [
7232
7777
  {
7233
7778
  "name": "project_id",
@@ -7237,46 +7782,115 @@ const routes = {
7237
7782
  "in": "path"
7238
7783
  },
7239
7784
  {
7240
- "name": "dataset_id",
7241
- "description": "Dataset ID",
7785
+ "name": "document_id",
7786
+ "description": "Document ID",
7242
7787
  "required": true,
7243
7788
  "type": "string",
7244
7789
  "in": "path"
7245
7790
  },
7246
7791
  {
7247
- "name": "generation_id",
7248
- "description": "The completed generation to promote. Must belong to the same project as the dataset.",
7249
- "required": true,
7792
+ "name": "wait",
7793
+ "description": "When omitted or `false` (default), processing runs in the background and `202 Accepted` is returned immediately with `status=pending`. Pass `true` to block until processing completes and receive `201 Created` with `status=ready`.",
7794
+ "required": false,
7795
+ "type": "boolean",
7796
+ "in": "query"
7797
+ },
7798
+ {
7799
+ "name": "chunk_strategy",
7800
+ "description": "How to split the source into chunks. Defaults to `page`.",
7801
+ "required": false,
7250
7802
  "type": "string",
7251
7803
  "in": "body"
7252
7804
  },
7253
7805
  {
7254
- "name": "expected_output",
7255
- "description": "Reference answer. Omit to use the generation's own answer; pass `null` to store the item with no reference answer.",
7806
+ "name": "chunk_size",
7807
+ "description": "Window size in characters when `chunk_strategy=size`. Defaults to 1000.",
7256
7808
  "required": false,
7257
- "type": "string",
7809
+ "type": "integer",
7258
7810
  "in": "body"
7259
7811
  },
7260
7812
  {
7261
- "name": "metadata",
7262
- "description": "Free-form tags, opaque to the platform",
7813
+ "name": "chunk_overlap",
7814
+ "description": "Overlap in characters between consecutive windows when `chunk_strategy=size`. Defaults to 200.",
7263
7815
  "required": false,
7264
- "type": "object",
7816
+ "type": "integer",
7265
7817
  "in": "body"
7266
7818
  }
7267
7819
  ]
7268
7820
  },
7269
- "update-dataset-item": {
7270
- serviceClass: "Evaluations",
7271
- operationId: "updateDatasetItem",
7272
- description: "Updates a test case. Runs that already scored it are unaffected — each result carries its own frozen copy of the input and expected output.",
7273
- moduleDocsUrl: "https://docs.naturali.ai/docs/modules/evaluations",
7821
+ "get-document-tags": {
7822
+ serviceClass: "Documents",
7823
+ operationId: "getDocumentTags",
7824
+ description: "Returns all tags attached to the document",
7825
+ moduleDocsUrl: "https://docs.naturali.ai/docs/modules/documents",
7826
+ httpMethod: "get",
7827
+ pathParams: ["project_id", "document_id"],
7828
+ queryParams: [],
7829
+ flags: [{
7830
+ "name": "project_id",
7831
+ "description": "Project public ID (proj_ prefix).",
7832
+ "required": true,
7833
+ "type": "string",
7834
+ "in": "path"
7835
+ }, {
7836
+ "name": "document_id",
7837
+ "description": "Document ID",
7838
+ "required": true,
7839
+ "type": "string",
7840
+ "in": "path"
7841
+ }]
7842
+ },
7843
+ "replace-document-tags": {
7844
+ serviceClass: "Documents",
7845
+ operationId: "replaceDocumentTags",
7846
+ description: "Replaces all tags on the document with the provided tags (not merged)",
7847
+ moduleDocsUrl: "https://docs.naturali.ai/docs/modules/documents",
7274
7848
  httpMethod: "put",
7275
- pathParams: [
7276
- "project_id",
7277
- "dataset_id",
7278
- "item_id"
7279
- ],
7849
+ pathParams: ["project_id", "document_id"],
7850
+ queryParams: [],
7851
+ flags: [{
7852
+ "name": "project_id",
7853
+ "description": "Project public ID (proj_ prefix).",
7854
+ "required": true,
7855
+ "type": "string",
7856
+ "in": "path"
7857
+ }, {
7858
+ "name": "document_id",
7859
+ "description": "Document ID",
7860
+ "required": true,
7861
+ "type": "string",
7862
+ "in": "path"
7863
+ }]
7864
+ },
7865
+ "merge-document-tags": {
7866
+ serviceClass: "Documents",
7867
+ operationId: "mergeDocumentTags",
7868
+ description: "Merges provided tags with existing tags (existing tags are preserved unless overridden)",
7869
+ moduleDocsUrl: "https://docs.naturali.ai/docs/modules/documents",
7870
+ httpMethod: "patch",
7871
+ pathParams: ["project_id", "document_id"],
7872
+ queryParams: [],
7873
+ flags: [{
7874
+ "name": "project_id",
7875
+ "description": "Project public ID (proj_ prefix).",
7876
+ "required": true,
7877
+ "type": "string",
7878
+ "in": "path"
7879
+ }, {
7880
+ "name": "document_id",
7881
+ "description": "Document ID",
7882
+ "required": true,
7883
+ "type": "string",
7884
+ "in": "path"
7885
+ }]
7886
+ },
7887
+ "create-embeddings": {
7888
+ serviceClass: "Embeddings",
7889
+ operationId: "createEmbeddings",
7890
+ description: "Generates embedding vectors for one or more text inputs using the server's configured embedding model. Provide `input` for a single text or `inputs` for a batch. At least one is required. Returns `embedding` when `input` is used, and `embeddings` when `inputs` is used.",
7891
+ moduleDocsUrl: "https://docs.naturali.ai/docs/modules/embeddings",
7892
+ httpMethod: "post",
7893
+ pathParams: ["project_id"],
7280
7894
  queryParams: [],
7281
7895
  flags: [
7282
7896
  {
@@ -7286,83 +7900,26 @@ const routes = {
7286
7900
  "type": "string",
7287
7901
  "in": "path"
7288
7902
  },
7289
- {
7290
- "name": "dataset_id",
7291
- "description": "Dataset ID",
7292
- "required": true,
7293
- "type": "string",
7294
- "in": "path"
7295
- },
7296
- {
7297
- "name": "item_id",
7298
- "description": "Dataset item ID",
7299
- "required": true,
7300
- "type": "string",
7301
- "in": "path"
7302
- },
7303
7903
  {
7304
7904
  "name": "input",
7305
- "description": "Messages replayed verbatim as the generation's input",
7306
- "required": false,
7307
- "type": "array",
7308
- "in": "body"
7309
- },
7310
- {
7311
- "name": "expected_output",
7312
- "description": "",
7905
+ "description": "Single text to embed.",
7313
7906
  "required": false,
7314
7907
  "type": "string",
7315
7908
  "in": "body"
7316
7909
  },
7317
7910
  {
7318
- "name": "metadata",
7319
- "description": "",
7911
+ "name": "inputs",
7912
+ "description": "Batch of texts to embed.",
7320
7913
  "required": false,
7321
- "type": "object",
7914
+ "type": "array",
7322
7915
  "in": "body"
7323
7916
  }
7324
7917
  ]
7325
7918
  },
7326
- "delete-dataset-item": {
7327
- serviceClass: "Evaluations",
7328
- operationId: "deleteDatasetItem",
7329
- description: "Deletes a test case. Results of runs that already scored it stay readable; their `dataset_item_id` becomes null.",
7330
- moduleDocsUrl: "https://docs.naturali.ai/docs/modules/evaluations",
7331
- httpMethod: "delete",
7332
- pathParams: [
7333
- "project_id",
7334
- "dataset_id",
7335
- "item_id"
7336
- ],
7337
- queryParams: [],
7338
- flags: [
7339
- {
7340
- "name": "project_id",
7341
- "description": "Project public ID (proj_ prefix).",
7342
- "required": true,
7343
- "type": "string",
7344
- "in": "path"
7345
- },
7346
- {
7347
- "name": "dataset_id",
7348
- "description": "Dataset ID",
7349
- "required": true,
7350
- "type": "string",
7351
- "in": "path"
7352
- },
7353
- {
7354
- "name": "item_id",
7355
- "description": "Dataset item ID",
7356
- "required": true,
7357
- "type": "string",
7358
- "in": "path"
7359
- }
7360
- ]
7361
- },
7362
- "list-evals": {
7919
+ "list-datasets": {
7363
7920
  serviceClass: "Evaluations",
7364
- operationId: "listEvals",
7365
- description: "Returns the evals defined in a project",
7921
+ operationId: "listDatasets",
7922
+ description: "Returns the datasets defined in a project",
7366
7923
  moduleDocsUrl: "https://docs.naturali.ai/docs/modules/evaluations",
7367
7924
  httpMethod: "get",
7368
7925
  pathParams: ["project_id"],
@@ -7391,10 +7948,10 @@ const routes = {
7391
7948
  }
7392
7949
  ]
7393
7950
  },
7394
- "create-eval": {
7951
+ "create-dataset": {
7395
7952
  serviceClass: "Evaluations",
7396
- operationId: "createEval",
7397
- description: "Binds an agent under test to a dataset and a list of scorers. The agent and the dataset must belong to the same project as the eval; a cross-project reference is rejected with 400. Scorer config is frozen here rather than read from the agent at run time, so two runs of the same eval are always judged by the same criteria and their comparison measures the agent instead of the config drifting underneath it. Each scorer `type` may appear at most once.",
7953
+ operationId: "createDataset",
7954
+ description: "Creates a project-scoped dataset a named collection of test cases an eval runs an agent against. Names are unique per project. Datasets are operator-owned **fixtures**. The platform's content purge never deletes or mutates a dataset item, so erasing a generation cannot silently stop a test suite from being runnable.",
7398
7955
  moduleDocsUrl: "https://docs.naturali.ai/docs/modules/evaluations",
7399
7956
  httpMethod: "post",
7400
7957
  pathParams: ["project_id"],
@@ -7415,42 +7972,21 @@ const routes = {
7415
7972
  "in": "body"
7416
7973
  },
7417
7974
  {
7418
- "name": "agent_id",
7419
- "description": "The agent under test",
7420
- "required": true,
7421
- "type": "string",
7422
- "in": "body"
7423
- },
7424
- {
7425
- "name": "dataset_id",
7426
- "description": "The dataset to run it against",
7427
- "required": true,
7428
- "type": "string",
7429
- "in": "body"
7430
- },
7431
- {
7432
- "name": "scorers",
7433
- "description": "Scorer configs, a discriminated union on `type`. Each type may appear at most once. Every scorer produces `{ score: 0–1, passed: boolean }`; binary scorers emit 0 or 1.\n\n`exact_match` compares the trimmed output text to `expected_output`. `contains` looks for `value` in the output text. `json_logic` evaluates `expression` over `{ input, output, object, expected, item.metadata }`, where `object` is the structured output (absent when the agent has no `output_schema`). `output_schema` validates the structured output against the scorer's own `schema`, falling back to the agent's; it requires the agent to carry an `output_schema`, because without one the platform emits no structured output and every item would score 0.\n\n`llm_judge` grades the output with a model completion, returning a continuous score plus its `reasoning`. Its `pass_threshold` is required: a continuous score says nothing about where \"good enough\" is, and a defaulted cutoff would silently decide the gate.\n\n`embedding_similarity` embeds the output text and `expected_output` with the platform's configured embedding model (`EMBEDDING_PROVIDER` / `EMBEDDING_MODEL` — the same stack document ingestion uses) and scores their cosine similarity, clamped to 0-1. Its `pass_threshold` is required for the same reason as the judge's. An item without an `expected_output` scores 0; an embedding backend failure marks the **item** errored, never a score of 0.\n\n`tool` runs a custom scoring algorithm: a server-callable project tool the engine invokes once per item with the item's context. Unlike the built-in types it may appear several times, each under a distinct `name` — outcomes and aggregates key on the name.",
7434
- "required": true,
7435
- "type": "array",
7436
- "in": "body"
7437
- },
7438
- {
7439
- "name": "pass_threshold",
7440
- "description": "0–1. The run passes iff its pass rate — passed items over non-errored items — is at least this. Null reports scores without gating on them.",
7975
+ "name": "description",
7976
+ "description": "What this suite covers",
7441
7977
  "required": false,
7442
- "type": "number",
7978
+ "type": "string",
7443
7979
  "in": "body"
7444
7980
  }
7445
7981
  ]
7446
7982
  },
7447
- "get-eval": {
7983
+ "get-dataset": {
7448
7984
  serviceClass: "Evaluations",
7449
- operationId: "getEval",
7450
- description: "Returns a specific eval",
7985
+ operationId: "getDataset",
7986
+ description: "Returns a specific dataset",
7451
7987
  moduleDocsUrl: "https://docs.naturali.ai/docs/modules/evaluations",
7452
7988
  httpMethod: "get",
7453
- pathParams: ["project_id", "eval_id"],
7989
+ pathParams: ["project_id", "dataset_id"],
7454
7990
  queryParams: [],
7455
7991
  flags: [{
7456
7992
  "name": "project_id",
@@ -7459,20 +7995,20 @@ const routes = {
7459
7995
  "type": "string",
7460
7996
  "in": "path"
7461
7997
  }, {
7462
- "name": "eval_id",
7463
- "description": "Eval ID",
7998
+ "name": "dataset_id",
7999
+ "description": "Dataset ID",
7464
8000
  "required": true,
7465
8001
  "type": "string",
7466
8002
  "in": "path"
7467
8003
  }]
7468
8004
  },
7469
- "update-eval": {
8005
+ "update-dataset": {
7470
8006
  serviceClass: "Evaluations",
7471
- operationId: "updateEval",
7472
- description: "Updates an eval. Changing `agent_id` re-validates the scorers against the new agent, since an `output_schema` scorer that was legal against the old one may not be.",
7473
- moduleDocsUrl: "https://docs.naturali.ai/docs/modules/evaluations",
8007
+ operationId: "updateDataset",
8008
+ description: "Updates a dataset's name and/or description",
8009
+ moduleDocsUrl: "https://docs.naturali.ai/docs/modules/evaluations",
7474
8010
  httpMethod: "put",
7475
- pathParams: ["project_id", "eval_id"],
8011
+ pathParams: ["project_id", "dataset_id"],
7476
8012
  queryParams: [],
7477
8013
  flags: [
7478
8014
  {
@@ -7483,8 +8019,8 @@ const routes = {
7483
8019
  "in": "path"
7484
8020
  },
7485
8021
  {
7486
- "name": "eval_id",
7487
- "description": "Eval ID",
8022
+ "name": "dataset_id",
8023
+ "description": "Dataset ID",
7488
8024
  "required": true,
7489
8025
  "type": "string",
7490
8026
  "in": "path"
@@ -7497,42 +8033,21 @@ const routes = {
7497
8033
  "in": "body"
7498
8034
  },
7499
8035
  {
7500
- "name": "agent_id",
7501
- "description": "",
7502
- "required": false,
7503
- "type": "string",
7504
- "in": "body"
7505
- },
7506
- {
7507
- "name": "dataset_id",
8036
+ "name": "description",
7508
8037
  "description": "",
7509
8038
  "required": false,
7510
8039
  "type": "string",
7511
8040
  "in": "body"
7512
- },
7513
- {
7514
- "name": "scorers",
7515
- "description": "Scorer configs, a discriminated union on `type`. Each type may appear at most once. Every scorer produces `{ score: 0–1, passed: boolean }`; binary scorers emit 0 or 1.\n\n`exact_match` compares the trimmed output text to `expected_output`. `contains` looks for `value` in the output text. `json_logic` evaluates `expression` over `{ input, output, object, expected, item.metadata }`, where `object` is the structured output (absent when the agent has no `output_schema`). `output_schema` validates the structured output against the scorer's own `schema`, falling back to the agent's; it requires the agent to carry an `output_schema`, because without one the platform emits no structured output and every item would score 0.\n\n`llm_judge` grades the output with a model completion, returning a continuous score plus its `reasoning`. Its `pass_threshold` is required: a continuous score says nothing about where \"good enough\" is, and a defaulted cutoff would silently decide the gate.\n\n`embedding_similarity` embeds the output text and `expected_output` with the platform's configured embedding model (`EMBEDDING_PROVIDER` / `EMBEDDING_MODEL` — the same stack document ingestion uses) and scores their cosine similarity, clamped to 0-1. Its `pass_threshold` is required for the same reason as the judge's. An item without an `expected_output` scores 0; an embedding backend failure marks the **item** errored, never a score of 0.\n\n`tool` runs a custom scoring algorithm: a server-callable project tool the engine invokes once per item with the item's context. Unlike the built-in types it may appear several times, each under a distinct `name` — outcomes and aggregates key on the name.",
7516
- "required": false,
7517
- "type": "array",
7518
- "in": "body"
7519
- },
7520
- {
7521
- "name": "pass_threshold",
7522
- "description": "",
7523
- "required": false,
7524
- "type": "number",
7525
- "in": "body"
7526
8041
  }
7527
8042
  ]
7528
8043
  },
7529
- "delete-eval": {
8044
+ "delete-dataset": {
7530
8045
  serviceClass: "Evaluations",
7531
- operationId: "deleteEval",
7532
- description: "Deletes an eval, its runs, and their results",
8046
+ operationId: "deleteDataset",
8047
+ description: "Deletes a dataset, its items, and every eval bound to it. Results of runs that already scored those items keep their frozen copies of the input and expected output.",
7533
8048
  moduleDocsUrl: "https://docs.naturali.ai/docs/modules/evaluations",
7534
8049
  httpMethod: "delete",
7535
- pathParams: ["project_id", "eval_id"],
8050
+ pathParams: ["project_id", "dataset_id"],
7536
8051
  queryParams: [],
7537
8052
  flags: [{
7538
8053
  "name": "project_id",
@@ -7541,20 +8056,20 @@ const routes = {
7541
8056
  "type": "string",
7542
8057
  "in": "path"
7543
8058
  }, {
7544
- "name": "eval_id",
7545
- "description": "Eval ID",
8059
+ "name": "dataset_id",
8060
+ "description": "Dataset ID",
7546
8061
  "required": true,
7547
8062
  "type": "string",
7548
8063
  "in": "path"
7549
8064
  }]
7550
8065
  },
7551
- "list-eval-runs": {
8066
+ "list-dataset-items": {
7552
8067
  serviceClass: "Evaluations",
7553
- operationId: "listEvalRuns",
7554
- description: "Returns an eval's runs, newest first",
8068
+ operationId: "listDatasetItems",
8069
+ description: "Returns the test cases in a dataset, oldest first",
7555
8070
  moduleDocsUrl: "https://docs.naturali.ai/docs/modules/evaluations",
7556
8071
  httpMethod: "get",
7557
- pathParams: ["project_id", "eval_id"],
8072
+ pathParams: ["project_id", "dataset_id"],
7558
8073
  queryParams: ["limit", "offset"],
7559
8074
  flags: [
7560
8075
  {
@@ -7565,8 +8080,8 @@ const routes = {
7565
8080
  "in": "path"
7566
8081
  },
7567
8082
  {
7568
- "name": "eval_id",
7569
- "description": "Eval ID",
8083
+ "name": "dataset_id",
8084
+ "description": "Dataset ID",
7570
8085
  "required": true,
7571
8086
  "type": "string",
7572
8087
  "in": "path"
@@ -7587,13 +8102,13 @@ const routes = {
7587
8102
  }
7588
8103
  ]
7589
8104
  },
7590
- "start-eval-run": {
8105
+ "create-dataset-item": {
7591
8106
  serviceClass: "Evaluations",
7592
- operationId: "startEvalRun",
7593
- description: "Runs the eval against its dataset, creating one real agent generation per item and scoring the outputs. `wait: true` executes the run synchronously and returns it terminal, with its scores. The dataset is capped at 25 items for a synchronous run; a larger one is rejected with 400 rather than partially scored. `wait: false` (the default) enqueues one task per item and returns immediately with `status: \"queued\"`. A worker executes the items and the run settles itself; poll `GET /evals/{eval_id}/runs/{eval_run_id}` for the terminal status. There is no item cap on a queued run. The whole run is pinned to **one** agent version, stamped on `agent_version`: pass one explicitly to evaluate a canary before promoting it, or omit it to use the active release's stable version (or the live draft when no release is in effect). Without the pin, release assignment would bucket each item independently and blend two configs into a single score. With `baseline_run_id`, the finished run's `aggregate_scores.baseline` carries per-scorer deltas against that run, computed over the items present and scorable in **both** runs, with the divergence counted. A delta over a shifted dataset is therefore never presented as a clean comparison.",
8107
+ operationId: "createDatasetItem",
8108
+ description: "Adds one test case. `input` is replayed verbatim as the generation's messages, so it must be a non-empty array of `{ role, content }`.",
7594
8109
  moduleDocsUrl: "https://docs.naturali.ai/docs/modules/evaluations",
7595
8110
  httpMethod: "post",
7596
- pathParams: ["project_id", "eval_id"],
8111
+ pathParams: ["project_id", "dataset_id"],
7597
8112
  queryParams: [],
7598
8113
  flags: [
7599
8114
  {
@@ -7604,46 +8119,42 @@ const routes = {
7604
8119
  "in": "path"
7605
8120
  },
7606
8121
  {
7607
- "name": "eval_id",
7608
- "description": "Eval ID",
8122
+ "name": "dataset_id",
8123
+ "description": "Dataset ID",
7609
8124
  "required": true,
7610
8125
  "type": "string",
7611
8126
  "in": "path"
7612
8127
  },
7613
8128
  {
7614
- "name": "wait",
7615
- "description": "True runs the eval synchronously (25-item cap) and returns a terminal run with its scores. False — the default — enqueues the items and returns a `queued` run immediately.",
7616
- "required": false,
7617
- "type": "boolean",
8129
+ "name": "input",
8130
+ "description": "Messages replayed verbatim as the generation's input",
8131
+ "required": true,
8132
+ "type": "array",
7618
8133
  "in": "body"
7619
8134
  },
7620
8135
  {
7621
- "name": "agent_version",
7622
- "description": "An archived agent version to evaluate. Defaults to the active release's stable version, or the live draft version when no release is in effect.",
8136
+ "name": "expected_output",
8137
+ "description": "Reference answer for exact_match / embedding_similarity / llm_judge scorers",
7623
8138
  "required": false,
7624
- "type": "integer",
8139
+ "type": "string",
7625
8140
  "in": "body"
7626
8141
  },
7627
8142
  {
7628
- "name": "baseline_run_id",
7629
- "description": "A terminal run of the same eval to compare against. The finished run's `aggregate_scores.baseline` reports per-scorer deltas over the item intersection. A run of a different eval is rejected with 400.",
8143
+ "name": "metadata",
8144
+ "description": "Free-form tags, opaque to the platform",
7630
8145
  "required": false,
7631
- "type": "string",
8146
+ "type": "object",
7632
8147
  "in": "body"
7633
8148
  }
7634
8149
  ]
7635
8150
  },
7636
- "get-eval-run": {
8151
+ "create-dataset-item-from-generation": {
7637
8152
  serviceClass: "Evaluations",
7638
- operationId: "getEvalRun",
7639
- description: "Returns a run's status, counts, and aggregate scores",
8153
+ operationId: "createDatasetItemFromGeneration",
8154
+ description: "Promotes a real, completed generation into a test case: its input messages become the item's `input`, and its own answer becomes `expected_output` unless you supply one. Use it to build an evaluation set out of production traffic rather than hand-authoring fixtures. The item is a **copy**, not a view. It keeps working after the source generation's content is purged, and `source_generation_id` goes null if that generation is deleted — a purge can never quietly stop a suite from being runnable. Requires both `evaluations:CreateDataset` and `generations:GetGeneration`: the call copies content out of a generation, so a principal that may not read that generation may not curate it either. Only a **completed** generation can be promoted (`409 GENERATION_NOT_COMPLETED`), and only while its content is still available: an agent or project running with `trace_content_mode: none` never stored the input, and a purged or expired generation no longer has it (`409 GENERATION_CONTENT_UNAVAILABLE`). Generations that predate input recording answer the same way.",
7640
8155
  moduleDocsUrl: "https://docs.naturali.ai/docs/modules/evaluations",
7641
- httpMethod: "get",
7642
- pathParams: [
7643
- "project_id",
7644
- "eval_id",
7645
- "eval_run_id"
7646
- ],
8156
+ httpMethod: "post",
8157
+ pathParams: ["project_id", "dataset_id"],
7647
8158
  queryParams: [],
7648
8159
  flags: [
7649
8160
  {
@@ -7654,33 +8165,47 @@ const routes = {
7654
8165
  "in": "path"
7655
8166
  },
7656
8167
  {
7657
- "name": "eval_id",
7658
- "description": "Eval ID",
8168
+ "name": "dataset_id",
8169
+ "description": "Dataset ID",
7659
8170
  "required": true,
7660
8171
  "type": "string",
7661
8172
  "in": "path"
7662
8173
  },
7663
8174
  {
7664
- "name": "eval_run_id",
7665
- "description": "Eval run ID",
8175
+ "name": "generation_id",
8176
+ "description": "The completed generation to promote. Must belong to the same project as the dataset.",
7666
8177
  "required": true,
7667
8178
  "type": "string",
7668
- "in": "path"
8179
+ "in": "body"
8180
+ },
8181
+ {
8182
+ "name": "expected_output",
8183
+ "description": "Reference answer. Omit to use the generation's own answer; pass `null` to store the item with no reference answer.",
8184
+ "required": false,
8185
+ "type": "string",
8186
+ "in": "body"
8187
+ },
8188
+ {
8189
+ "name": "metadata",
8190
+ "description": "Free-form tags, opaque to the platform",
8191
+ "required": false,
8192
+ "type": "object",
8193
+ "in": "body"
7669
8194
  }
7670
8195
  ]
7671
8196
  },
7672
- "list-eval-results": {
8197
+ "update-dataset-item": {
7673
8198
  serviceClass: "Evaluations",
7674
- operationId: "listEvalResults",
7675
- description: "Returns the per-item results of a run, oldest first",
8199
+ operationId: "updateDatasetItem",
8200
+ description: "Updates a test case. Runs that already scored it are unaffected — each result carries its own frozen copy of the input and expected output.",
7676
8201
  moduleDocsUrl: "https://docs.naturali.ai/docs/modules/evaluations",
7677
- httpMethod: "get",
8202
+ httpMethod: "put",
7678
8203
  pathParams: [
7679
8204
  "project_id",
7680
- "eval_id",
7681
- "eval_run_id"
8205
+ "dataset_id",
8206
+ "item_id"
7682
8207
  ],
7683
- queryParams: ["limit", "offset"],
8208
+ queryParams: [],
7684
8209
  flags: [
7685
8210
  {
7686
8211
  "name": "project_id",
@@ -7690,45 +8215,52 @@ const routes = {
7690
8215
  "in": "path"
7691
8216
  },
7692
8217
  {
7693
- "name": "eval_id",
7694
- "description": "Eval ID",
8218
+ "name": "dataset_id",
8219
+ "description": "Dataset ID",
7695
8220
  "required": true,
7696
8221
  "type": "string",
7697
8222
  "in": "path"
7698
8223
  },
7699
8224
  {
7700
- "name": "eval_run_id",
7701
- "description": "Eval run ID",
8225
+ "name": "item_id",
8226
+ "description": "Dataset item ID",
7702
8227
  "required": true,
7703
8228
  "type": "string",
7704
8229
  "in": "path"
7705
8230
  },
7706
8231
  {
7707
- "name": "limit",
7708
- "description": "Maximum number of results to return",
8232
+ "name": "input",
8233
+ "description": "Messages replayed verbatim as the generation's input",
7709
8234
  "required": false,
7710
- "type": "integer",
7711
- "in": "query"
8235
+ "type": "array",
8236
+ "in": "body"
7712
8237
  },
7713
8238
  {
7714
- "name": "offset",
7715
- "description": "Number of results to skip",
8239
+ "name": "expected_output",
8240
+ "description": "",
7716
8241
  "required": false,
7717
- "type": "integer",
7718
- "in": "query"
8242
+ "type": "string",
8243
+ "in": "body"
8244
+ },
8245
+ {
8246
+ "name": "metadata",
8247
+ "description": "",
8248
+ "required": false,
8249
+ "type": "object",
8250
+ "in": "body"
7719
8251
  }
7720
8252
  ]
7721
8253
  },
7722
- "cancel-eval-run": {
8254
+ "delete-dataset-item": {
7723
8255
  serviceClass: "Evaluations",
7724
- operationId: "cancelEvalRun",
7725
- description: "Cancels a queued or running run: its outstanding item tasks are dropped so it stops consuming provider budget, and the run settles as `canceled`. Results already written are kept — they are real measurements of generations that were really paid for and `completed_count` / `errored_count` report what ran. `aggregate_scores` is deliberately left null: a partial roll-up in the same field a completed run uses would read as a whole-dataset verdict. A run that has already finished is rejected with 400.",
8256
+ operationId: "deleteDatasetItem",
8257
+ description: "Deletes a test case. Results of runs that already scored it stay readable; their `dataset_item_id` becomes null.",
7726
8258
  moduleDocsUrl: "https://docs.naturali.ai/docs/modules/evaluations",
7727
- httpMethod: "post",
8259
+ httpMethod: "delete",
7728
8260
  pathParams: [
7729
8261
  "project_id",
7730
- "eval_id",
7731
- "eval_run_id"
8262
+ "dataset_id",
8263
+ "item_id"
7732
8264
  ],
7733
8265
  queryParams: [],
7734
8266
  flags: [
@@ -7740,36 +8272,29 @@ const routes = {
7740
8272
  "in": "path"
7741
8273
  },
7742
8274
  {
7743
- "name": "eval_id",
7744
- "description": "Eval ID",
8275
+ "name": "dataset_id",
8276
+ "description": "Dataset ID",
7745
8277
  "required": true,
7746
8278
  "type": "string",
7747
8279
  "in": "path"
7748
8280
  },
7749
8281
  {
7750
- "name": "eval_run_id",
7751
- "description": "Eval run ID",
8282
+ "name": "item_id",
8283
+ "description": "Dataset item ID",
7752
8284
  "required": true,
7753
8285
  "type": "string",
7754
8286
  "in": "path"
7755
8287
  }
7756
8288
  ]
7757
8289
  },
7758
- "list-generations": {
7759
- serviceClass: "Generations",
7760
- operationId: "listGenerations",
7761
- description: "Returns generations the caller can access, optionally filtered by agent, trace, and status. Replaces the former per-trace generations endpoint (use the trace_id query filter).",
7762
- moduleDocsUrl: "https://docs.naturali.ai/docs/modules/generations",
8290
+ "list-evals": {
8291
+ serviceClass: "Evaluations",
8292
+ operationId: "listEvals",
8293
+ description: "Returns the evals defined in a project",
8294
+ moduleDocsUrl: "https://docs.naturali.ai/docs/modules/evaluations",
7763
8295
  httpMethod: "get",
7764
8296
  pathParams: ["project_id"],
7765
- queryParams: [
7766
- "agent_id",
7767
- "trace_id",
7768
- "initiator_generation_id",
7769
- "status",
7770
- "limit",
7771
- "offset"
7772
- ],
8297
+ queryParams: ["limit", "offset"],
7773
8298
  flags: [
7774
8299
  {
7775
8300
  "name": "project_id",
@@ -7778,57 +8303,890 @@ const routes = {
7778
8303
  "type": "string",
7779
8304
  "in": "path"
7780
8305
  },
7781
- {
7782
- "name": "agent_id",
7783
- "description": "Filter by agent public ID",
7784
- "required": false,
7785
- "type": "string",
7786
- "in": "query"
7787
- },
7788
- {
7789
- "name": "trace_id",
7790
- "description": "Filter by trace public ID",
7791
- "required": false,
7792
- "type": "string",
7793
- "in": "query"
7794
- },
7795
- {
7796
- "name": "initiator_generation_id",
7797
- "description": "Filter by the public ID of the parent generation. Returns all generations triggered by that generation — sub-agent invocations. Null-initiated (top-level) generations are not returned.\n",
7798
- "required": false,
7799
- "type": "string",
7800
- "in": "query"
7801
- },
7802
- {
7803
- "name": "status",
7804
- "description": "Filter by lifecycle status",
7805
- "required": false,
7806
- "type": "string",
7807
- "in": "query"
7808
- },
7809
8306
  {
7810
8307
  "name": "limit",
7811
- "description": "",
8308
+ "description": "Maximum number of results to return",
7812
8309
  "required": false,
7813
8310
  "type": "integer",
7814
8311
  "in": "query"
7815
8312
  },
7816
8313
  {
7817
8314
  "name": "offset",
7818
- "description": "",
8315
+ "description": "Number of results to skip",
7819
8316
  "required": false,
7820
8317
  "type": "integer",
7821
8318
  "in": "query"
7822
8319
  }
7823
8320
  ]
7824
8321
  },
7825
- "get-generation": {
7826
- serviceClass: "Generations",
7827
- operationId: "getGeneration",
7828
- description: "Returns a single generation record by ID, including its status and the structured `error` payload when the generation failed (e.g. because the upstream AI provider returned an error).",
7829
- moduleDocsUrl: "https://docs.naturali.ai/docs/modules/generations",
7830
- httpMethod: "get",
7831
- pathParams: ["project_id", "generation_id"],
8322
+ "create-eval": {
8323
+ serviceClass: "Evaluations",
8324
+ operationId: "createEval",
8325
+ description: "Binds an agent under test to a dataset and a list of scorers. The agent and the dataset must belong to the same project as the eval; a cross-project reference is rejected with 400. Scorer config is frozen here rather than read from the agent at run time, so two runs of the same eval are always judged by the same criteria and their comparison measures the agent instead of the config drifting underneath it. Each scorer `type` may appear at most once.",
8326
+ moduleDocsUrl: "https://docs.naturali.ai/docs/modules/evaluations",
8327
+ httpMethod: "post",
8328
+ pathParams: ["project_id"],
8329
+ queryParams: [],
8330
+ flags: [
8331
+ {
8332
+ "name": "project_id",
8333
+ "description": "Project public ID (proj_ prefix).",
8334
+ "required": true,
8335
+ "type": "string",
8336
+ "in": "path"
8337
+ },
8338
+ {
8339
+ "name": "name",
8340
+ "description": "Unique name within the project",
8341
+ "required": true,
8342
+ "type": "string",
8343
+ "in": "body"
8344
+ },
8345
+ {
8346
+ "name": "agent_id",
8347
+ "description": "The agent under test",
8348
+ "required": true,
8349
+ "type": "string",
8350
+ "in": "body"
8351
+ },
8352
+ {
8353
+ "name": "dataset_id",
8354
+ "description": "The dataset to run it against",
8355
+ "required": true,
8356
+ "type": "string",
8357
+ "in": "body"
8358
+ },
8359
+ {
8360
+ "name": "scorers",
8361
+ "description": "Scorer configs, a discriminated union on `type`. Each type may appear at most once. Every scorer produces `{ score: 0–1, passed: boolean }`; binary scorers emit 0 or 1.\n\n`exact_match` compares the trimmed output text to `expected_output`. `contains` looks for `value` in the output text. `json_logic` evaluates `expression` over `{ input, output, object, expected, item.metadata }`, where `object` is the structured output (absent when the agent has no `output_schema`). `output_schema` validates the structured output against the scorer's own `schema`, falling back to the agent's; it requires the agent to carry an `output_schema`, because without one the platform emits no structured output and every item would score 0.\n\n`llm_judge` grades the output with a model completion, returning a continuous score plus its `reasoning`. Its `pass_threshold` is required: a continuous score says nothing about where \"good enough\" is, and a defaulted cutoff would silently decide the gate.\n\n`embedding_similarity` embeds the output text and `expected_output` with the platform's configured embedding model (`EMBEDDING_PROVIDER` / `EMBEDDING_MODEL` — the same stack document ingestion uses) and scores their cosine similarity, clamped to 0-1. Its `pass_threshold` is required for the same reason as the judge's. An item without an `expected_output` scores 0; an embedding backend failure marks the **item** errored, never a score of 0.\n\n`tool` runs a custom scoring algorithm: a server-callable project tool the engine invokes once per item with the item's context. Unlike the built-in types it may appear several times, each under a distinct `name` — outcomes and aggregates key on the name.",
8362
+ "required": true,
8363
+ "type": "array",
8364
+ "in": "body"
8365
+ },
8366
+ {
8367
+ "name": "pass_threshold",
8368
+ "description": "0–1. The run passes iff its pass rate — passed items over non-errored items — is at least this. Null reports scores without gating on them.",
8369
+ "required": false,
8370
+ "type": "number",
8371
+ "in": "body"
8372
+ }
8373
+ ]
8374
+ },
8375
+ "get-eval": {
8376
+ serviceClass: "Evaluations",
8377
+ operationId: "getEval",
8378
+ description: "Returns a specific eval",
8379
+ moduleDocsUrl: "https://docs.naturali.ai/docs/modules/evaluations",
8380
+ httpMethod: "get",
8381
+ pathParams: ["project_id", "eval_id"],
8382
+ queryParams: [],
8383
+ flags: [{
8384
+ "name": "project_id",
8385
+ "description": "Project public ID (proj_ prefix).",
8386
+ "required": true,
8387
+ "type": "string",
8388
+ "in": "path"
8389
+ }, {
8390
+ "name": "eval_id",
8391
+ "description": "Eval ID",
8392
+ "required": true,
8393
+ "type": "string",
8394
+ "in": "path"
8395
+ }]
8396
+ },
8397
+ "update-eval": {
8398
+ serviceClass: "Evaluations",
8399
+ operationId: "updateEval",
8400
+ description: "Updates an eval. Changing `agent_id` re-validates the scorers against the new agent, since an `output_schema` scorer that was legal against the old one may not be.",
8401
+ moduleDocsUrl: "https://docs.naturali.ai/docs/modules/evaluations",
8402
+ httpMethod: "put",
8403
+ pathParams: ["project_id", "eval_id"],
8404
+ queryParams: [],
8405
+ flags: [
8406
+ {
8407
+ "name": "project_id",
8408
+ "description": "Project public ID (proj_ prefix).",
8409
+ "required": true,
8410
+ "type": "string",
8411
+ "in": "path"
8412
+ },
8413
+ {
8414
+ "name": "eval_id",
8415
+ "description": "Eval ID",
8416
+ "required": true,
8417
+ "type": "string",
8418
+ "in": "path"
8419
+ },
8420
+ {
8421
+ "name": "name",
8422
+ "description": "",
8423
+ "required": false,
8424
+ "type": "string",
8425
+ "in": "body"
8426
+ },
8427
+ {
8428
+ "name": "agent_id",
8429
+ "description": "",
8430
+ "required": false,
8431
+ "type": "string",
8432
+ "in": "body"
8433
+ },
8434
+ {
8435
+ "name": "dataset_id",
8436
+ "description": "",
8437
+ "required": false,
8438
+ "type": "string",
8439
+ "in": "body"
8440
+ },
8441
+ {
8442
+ "name": "scorers",
8443
+ "description": "Scorer configs, a discriminated union on `type`. Each type may appear at most once. Every scorer produces `{ score: 0–1, passed: boolean }`; binary scorers emit 0 or 1.\n\n`exact_match` compares the trimmed output text to `expected_output`. `contains` looks for `value` in the output text. `json_logic` evaluates `expression` over `{ input, output, object, expected, item.metadata }`, where `object` is the structured output (absent when the agent has no `output_schema`). `output_schema` validates the structured output against the scorer's own `schema`, falling back to the agent's; it requires the agent to carry an `output_schema`, because without one the platform emits no structured output and every item would score 0.\n\n`llm_judge` grades the output with a model completion, returning a continuous score plus its `reasoning`. Its `pass_threshold` is required: a continuous score says nothing about where \"good enough\" is, and a defaulted cutoff would silently decide the gate.\n\n`embedding_similarity` embeds the output text and `expected_output` with the platform's configured embedding model (`EMBEDDING_PROVIDER` / `EMBEDDING_MODEL` — the same stack document ingestion uses) and scores their cosine similarity, clamped to 0-1. Its `pass_threshold` is required for the same reason as the judge's. An item without an `expected_output` scores 0; an embedding backend failure marks the **item** errored, never a score of 0.\n\n`tool` runs a custom scoring algorithm: a server-callable project tool the engine invokes once per item with the item's context. Unlike the built-in types it may appear several times, each under a distinct `name` — outcomes and aggregates key on the name.",
8444
+ "required": false,
8445
+ "type": "array",
8446
+ "in": "body"
8447
+ },
8448
+ {
8449
+ "name": "pass_threshold",
8450
+ "description": "",
8451
+ "required": false,
8452
+ "type": "number",
8453
+ "in": "body"
8454
+ }
8455
+ ]
8456
+ },
8457
+ "delete-eval": {
8458
+ serviceClass: "Evaluations",
8459
+ operationId: "deleteEval",
8460
+ description: "Deletes an eval, its runs, and their results",
8461
+ moduleDocsUrl: "https://docs.naturali.ai/docs/modules/evaluations",
8462
+ httpMethod: "delete",
8463
+ pathParams: ["project_id", "eval_id"],
8464
+ queryParams: [],
8465
+ flags: [{
8466
+ "name": "project_id",
8467
+ "description": "Project public ID (proj_ prefix).",
8468
+ "required": true,
8469
+ "type": "string",
8470
+ "in": "path"
8471
+ }, {
8472
+ "name": "eval_id",
8473
+ "description": "Eval ID",
8474
+ "required": true,
8475
+ "type": "string",
8476
+ "in": "path"
8477
+ }]
8478
+ },
8479
+ "list-eval-runs": {
8480
+ serviceClass: "Evaluations",
8481
+ operationId: "listEvalRuns",
8482
+ description: "Returns an eval's runs, newest first",
8483
+ moduleDocsUrl: "https://docs.naturali.ai/docs/modules/evaluations",
8484
+ httpMethod: "get",
8485
+ pathParams: ["project_id", "eval_id"],
8486
+ queryParams: ["limit", "offset"],
8487
+ flags: [
8488
+ {
8489
+ "name": "project_id",
8490
+ "description": "Project public ID (proj_ prefix).",
8491
+ "required": true,
8492
+ "type": "string",
8493
+ "in": "path"
8494
+ },
8495
+ {
8496
+ "name": "eval_id",
8497
+ "description": "Eval ID",
8498
+ "required": true,
8499
+ "type": "string",
8500
+ "in": "path"
8501
+ },
8502
+ {
8503
+ "name": "limit",
8504
+ "description": "Maximum number of results to return",
8505
+ "required": false,
8506
+ "type": "integer",
8507
+ "in": "query"
8508
+ },
8509
+ {
8510
+ "name": "offset",
8511
+ "description": "Number of results to skip",
8512
+ "required": false,
8513
+ "type": "integer",
8514
+ "in": "query"
8515
+ }
8516
+ ]
8517
+ },
8518
+ "start-eval-run": {
8519
+ serviceClass: "Evaluations",
8520
+ operationId: "startEvalRun",
8521
+ description: "Runs the eval against its dataset, creating one real agent generation per item and scoring the outputs. `wait: true` executes the run synchronously and returns it terminal, with its scores. The dataset is capped at 25 items for a synchronous run; a larger one is rejected with 400 rather than partially scored. `wait: false` (the default) enqueues one task per item and returns immediately with `status: \"queued\"`. A worker executes the items and the run settles itself; poll `GET /evals/{eval_id}/runs/{eval_run_id}` for the terminal status. There is no item cap on a queued run. The whole run is pinned to **one** agent version, stamped on `agent_version`: pass one explicitly to evaluate a canary before promoting it, or omit it to use the active release's stable version (or the live draft when no release is in effect). Without the pin, release assignment would bucket each item independently and blend two configs into a single score. With `baseline_run_id`, the finished run's `aggregate_scores.baseline` carries per-scorer deltas against that run, computed over the items present and scorable in **both** runs, with the divergence counted. A delta over a shifted dataset is therefore never presented as a clean comparison.",
8522
+ moduleDocsUrl: "https://docs.naturali.ai/docs/modules/evaluations",
8523
+ httpMethod: "post",
8524
+ pathParams: ["project_id", "eval_id"],
8525
+ queryParams: [],
8526
+ flags: [
8527
+ {
8528
+ "name": "project_id",
8529
+ "description": "Project public ID (proj_ prefix).",
8530
+ "required": true,
8531
+ "type": "string",
8532
+ "in": "path"
8533
+ },
8534
+ {
8535
+ "name": "eval_id",
8536
+ "description": "Eval ID",
8537
+ "required": true,
8538
+ "type": "string",
8539
+ "in": "path"
8540
+ },
8541
+ {
8542
+ "name": "wait",
8543
+ "description": "True runs the eval synchronously (25-item cap) and returns a terminal run with its scores. False — the default — enqueues the items and returns a `queued` run immediately.",
8544
+ "required": false,
8545
+ "type": "boolean",
8546
+ "in": "body"
8547
+ },
8548
+ {
8549
+ "name": "agent_version",
8550
+ "description": "An archived agent version to evaluate. Defaults to the active release's stable version, or the live draft version when no release is in effect.",
8551
+ "required": false,
8552
+ "type": "integer",
8553
+ "in": "body"
8554
+ },
8555
+ {
8556
+ "name": "baseline_run_id",
8557
+ "description": "A terminal run of the same eval to compare against. The finished run's `aggregate_scores.baseline` reports per-scorer deltas over the item intersection. A run of a different eval is rejected with 400.",
8558
+ "required": false,
8559
+ "type": "string",
8560
+ "in": "body"
8561
+ }
8562
+ ]
8563
+ },
8564
+ "get-eval-run": {
8565
+ serviceClass: "Evaluations",
8566
+ operationId: "getEvalRun",
8567
+ description: "Returns a run's status, counts, and aggregate scores",
8568
+ moduleDocsUrl: "https://docs.naturali.ai/docs/modules/evaluations",
8569
+ httpMethod: "get",
8570
+ pathParams: [
8571
+ "project_id",
8572
+ "eval_id",
8573
+ "eval_run_id"
8574
+ ],
8575
+ queryParams: [],
8576
+ flags: [
8577
+ {
8578
+ "name": "project_id",
8579
+ "description": "Project public ID (proj_ prefix).",
8580
+ "required": true,
8581
+ "type": "string",
8582
+ "in": "path"
8583
+ },
8584
+ {
8585
+ "name": "eval_id",
8586
+ "description": "Eval ID",
8587
+ "required": true,
8588
+ "type": "string",
8589
+ "in": "path"
8590
+ },
8591
+ {
8592
+ "name": "eval_run_id",
8593
+ "description": "Eval run ID",
8594
+ "required": true,
8595
+ "type": "string",
8596
+ "in": "path"
8597
+ }
8598
+ ]
8599
+ },
8600
+ "list-eval-results": {
8601
+ serviceClass: "Evaluations",
8602
+ operationId: "listEvalResults",
8603
+ description: "Returns the per-item results of a run, oldest first",
8604
+ moduleDocsUrl: "https://docs.naturali.ai/docs/modules/evaluations",
8605
+ httpMethod: "get",
8606
+ pathParams: [
8607
+ "project_id",
8608
+ "eval_id",
8609
+ "eval_run_id"
8610
+ ],
8611
+ queryParams: ["limit", "offset"],
8612
+ flags: [
8613
+ {
8614
+ "name": "project_id",
8615
+ "description": "Project public ID (proj_ prefix).",
8616
+ "required": true,
8617
+ "type": "string",
8618
+ "in": "path"
8619
+ },
8620
+ {
8621
+ "name": "eval_id",
8622
+ "description": "Eval ID",
8623
+ "required": true,
8624
+ "type": "string",
8625
+ "in": "path"
8626
+ },
8627
+ {
8628
+ "name": "eval_run_id",
8629
+ "description": "Eval run ID",
8630
+ "required": true,
8631
+ "type": "string",
8632
+ "in": "path"
8633
+ },
8634
+ {
8635
+ "name": "limit",
8636
+ "description": "Maximum number of results to return",
8637
+ "required": false,
8638
+ "type": "integer",
8639
+ "in": "query"
8640
+ },
8641
+ {
8642
+ "name": "offset",
8643
+ "description": "Number of results to skip",
8644
+ "required": false,
8645
+ "type": "integer",
8646
+ "in": "query"
8647
+ }
8648
+ ]
8649
+ },
8650
+ "cancel-eval-run": {
8651
+ serviceClass: "Evaluations",
8652
+ operationId: "cancelEvalRun",
8653
+ description: "Cancels a queued or running run: its outstanding item tasks are dropped so it stops consuming provider budget, and the run settles as `canceled`. Results already written are kept — they are real measurements of generations that were really paid for — and `completed_count` / `errored_count` report what ran. `aggregate_scores` is deliberately left null: a partial roll-up in the same field a completed run uses would read as a whole-dataset verdict. A run that has already finished is rejected with 400.",
8654
+ moduleDocsUrl: "https://docs.naturali.ai/docs/modules/evaluations",
8655
+ httpMethod: "post",
8656
+ pathParams: [
8657
+ "project_id",
8658
+ "eval_id",
8659
+ "eval_run_id"
8660
+ ],
8661
+ queryParams: [],
8662
+ flags: [
8663
+ {
8664
+ "name": "project_id",
8665
+ "description": "Project public ID (proj_ prefix).",
8666
+ "required": true,
8667
+ "type": "string",
8668
+ "in": "path"
8669
+ },
8670
+ {
8671
+ "name": "eval_id",
8672
+ "description": "Eval ID",
8673
+ "required": true,
8674
+ "type": "string",
8675
+ "in": "path"
8676
+ },
8677
+ {
8678
+ "name": "eval_run_id",
8679
+ "description": "Eval run ID",
8680
+ "required": true,
8681
+ "type": "string",
8682
+ "in": "path"
8683
+ }
8684
+ ]
8685
+ },
8686
+ "list-files": {
8687
+ serviceClass: "Files",
8688
+ operationId: "listFiles",
8689
+ description: "Returns a list of all stored files",
8690
+ moduleDocsUrl: "https://docs.naturali.ai/docs/modules/files",
8691
+ httpMethod: "get",
8692
+ pathParams: ["project_id"],
8693
+ queryParams: ["limit", "offset"],
8694
+ flags: [
8695
+ {
8696
+ "name": "project_id",
8697
+ "description": "Project public ID (proj_ prefix).",
8698
+ "required": true,
8699
+ "type": "string",
8700
+ "in": "path"
8701
+ },
8702
+ {
8703
+ "name": "limit",
8704
+ "description": "Maximum number of results to return",
8705
+ "required": false,
8706
+ "type": "integer",
8707
+ "in": "query"
8708
+ },
8709
+ {
8710
+ "name": "offset",
8711
+ "description": "Number of results to skip",
8712
+ "required": false,
8713
+ "type": "integer",
8714
+ "in": "query"
8715
+ }
8716
+ ]
8717
+ },
8718
+ "create-file": {
8719
+ serviceClass: "Files",
8720
+ operationId: "createFile",
8721
+ description: "Creates a new file record in the system",
8722
+ moduleDocsUrl: "https://docs.naturali.ai/docs/modules/files",
8723
+ httpMethod: "post",
8724
+ pathParams: ["project_id"],
8725
+ queryParams: [],
8726
+ flags: [
8727
+ {
8728
+ "name": "project_id",
8729
+ "description": "Project public ID (proj_ prefix).",
8730
+ "required": true,
8731
+ "type": "string",
8732
+ "in": "path"
8733
+ },
8734
+ {
8735
+ "name": "prefix",
8736
+ "description": "Directory within the project (e.g. /images). Optional; defaults to / (root). Combined with filename to form the file's key (path).",
8737
+ "required": false,
8738
+ "type": "string",
8739
+ "in": "body"
8740
+ },
8741
+ {
8742
+ "name": "filename",
8743
+ "description": "Original / download name and the key's leaf segment (e.g. logo.png).",
8744
+ "required": false,
8745
+ "type": "string",
8746
+ "in": "body"
8747
+ },
8748
+ {
8749
+ "name": "content_type",
8750
+ "description": "MIME type of the file",
8751
+ "required": false,
8752
+ "type": "string",
8753
+ "in": "body"
8754
+ },
8755
+ {
8756
+ "name": "size",
8757
+ "description": "File size in bytes",
8758
+ "required": false,
8759
+ "type": "integer",
8760
+ "in": "body"
8761
+ },
8762
+ {
8763
+ "name": "metadata",
8764
+ "description": "JSON string with additional metadata",
8765
+ "required": false,
8766
+ "type": "string",
8767
+ "in": "body"
8768
+ }
8769
+ ]
8770
+ },
8771
+ "upload-file": {
8772
+ serviceClass: "Files",
8773
+ operationId: "uploadFile",
8774
+ description: "Uploads a file to the server and stores it in the configured storage directory",
8775
+ moduleDocsUrl: "https://docs.naturali.ai/docs/modules/files",
8776
+ httpMethod: "post",
8777
+ pathParams: ["project_id"],
8778
+ queryParams: [],
8779
+ flags: [{
8780
+ "name": "project_id",
8781
+ "description": "Project public ID (proj_ prefix).",
8782
+ "required": true,
8783
+ "type": "string",
8784
+ "in": "path"
8785
+ }]
8786
+ },
8787
+ "upload-file-base64": {
8788
+ serviceClass: "Files",
8789
+ operationId: "uploadFileBase64",
8790
+ description: "Uploads a file to the server using base64-encoded content",
8791
+ moduleDocsUrl: "https://docs.naturali.ai/docs/modules/files",
8792
+ httpMethod: "post",
8793
+ pathParams: ["project_id"],
8794
+ queryParams: [],
8795
+ flags: [
8796
+ {
8797
+ "name": "project_id",
8798
+ "description": "Project public ID (proj_ prefix).",
8799
+ "required": true,
8800
+ "type": "string",
8801
+ "in": "path"
8802
+ },
8803
+ {
8804
+ "name": "content",
8805
+ "description": "Base64-encoded file content",
8806
+ "required": true,
8807
+ "type": "string",
8808
+ "in": "body"
8809
+ },
8810
+ {
8811
+ "name": "prefix",
8812
+ "description": "Directory within the project (e.g. /documents). Optional; defaults to / (root).",
8813
+ "required": false,
8814
+ "type": "string",
8815
+ "in": "body"
8816
+ },
8817
+ {
8818
+ "name": "filename",
8819
+ "description": "Original / download name and the key's leaf segment.",
8820
+ "required": false,
8821
+ "type": "string",
8822
+ "in": "body"
8823
+ },
8824
+ {
8825
+ "name": "content_type",
8826
+ "description": "MIME type of the file",
8827
+ "required": false,
8828
+ "type": "string",
8829
+ "in": "body"
8830
+ },
8831
+ {
8832
+ "name": "metadata",
8833
+ "description": "JSON string with additional metadata",
8834
+ "required": false,
8835
+ "type": "string",
8836
+ "in": "body"
8837
+ }
8838
+ ]
8839
+ },
8840
+ "get-file": {
8841
+ serviceClass: "Files",
8842
+ operationId: "getFile",
8843
+ description: "Returns the data and metadata of a specific file",
8844
+ moduleDocsUrl: "https://docs.naturali.ai/docs/modules/files",
8845
+ httpMethod: "get",
8846
+ pathParams: ["project_id", "file_id"],
8847
+ queryParams: [],
8848
+ flags: [{
8849
+ "name": "project_id",
8850
+ "description": "Project public ID (proj_ prefix).",
8851
+ "required": true,
8852
+ "type": "string",
8853
+ "in": "path"
8854
+ }, {
8855
+ "name": "file_id",
8856
+ "description": "File ID",
8857
+ "required": true,
8858
+ "type": "string",
8859
+ "in": "path"
8860
+ }]
8861
+ },
8862
+ "delete-file": {
8863
+ serviceClass: "Files",
8864
+ operationId: "deleteFile",
8865
+ description: "Removes a file from the system by ID",
8866
+ moduleDocsUrl: "https://docs.naturali.ai/docs/modules/files",
8867
+ httpMethod: "delete",
8868
+ pathParams: ["project_id", "file_id"],
8869
+ queryParams: [],
8870
+ flags: [{
8871
+ "name": "project_id",
8872
+ "description": "Project public ID (proj_ prefix).",
8873
+ "required": true,
8874
+ "type": "string",
8875
+ "in": "path"
8876
+ }, {
8877
+ "name": "file_id",
8878
+ "description": "ID of the file to delete",
8879
+ "required": true,
8880
+ "type": "string",
8881
+ "in": "path"
8882
+ }]
8883
+ },
8884
+ "download-file": {
8885
+ serviceClass: "Files",
8886
+ operationId: "downloadFile",
8887
+ description: "Streams the file content to the client",
8888
+ moduleDocsUrl: "https://docs.naturali.ai/docs/modules/files",
8889
+ httpMethod: "get",
8890
+ pathParams: ["project_id", "file_id"],
8891
+ queryParams: [],
8892
+ flags: [{
8893
+ "name": "project_id",
8894
+ "description": "Project public ID (proj_ prefix).",
8895
+ "required": true,
8896
+ "type": "string",
8897
+ "in": "path"
8898
+ }, {
8899
+ "name": "file_id",
8900
+ "description": "File ID",
8901
+ "required": true,
8902
+ "type": "string",
8903
+ "in": "path"
8904
+ }]
8905
+ },
8906
+ "update-file-metadata": {
8907
+ serviceClass: "Files",
8908
+ operationId: "updateFileMetadata",
8909
+ description: "Updates the metadata field of a file",
8910
+ moduleDocsUrl: "https://docs.naturali.ai/docs/modules/files",
8911
+ httpMethod: "patch",
8912
+ pathParams: ["project_id", "file_id"],
8913
+ queryParams: [],
8914
+ flags: [
8915
+ {
8916
+ "name": "project_id",
8917
+ "description": "Project public ID (proj_ prefix).",
8918
+ "required": true,
8919
+ "type": "string",
8920
+ "in": "path"
8921
+ },
8922
+ {
8923
+ "name": "file_id",
8924
+ "description": "File ID",
8925
+ "required": true,
8926
+ "type": "string",
8927
+ "in": "path"
8928
+ },
8929
+ {
8930
+ "name": "metadata",
8931
+ "description": "New metadata as a JSON string",
8932
+ "required": false,
8933
+ "type": "string",
8934
+ "in": "body"
8935
+ },
8936
+ {
8937
+ "name": "prefix",
8938
+ "description": "New directory — moves the file. The resulting path (prefix + filename) must be unique within the project.",
8939
+ "required": false,
8940
+ "type": "string",
8941
+ "in": "body"
8942
+ },
8943
+ {
8944
+ "name": "filename",
8945
+ "description": "New filename — renames the key's leaf and the download name.",
8946
+ "required": false,
8947
+ "type": "string",
8948
+ "in": "body"
8949
+ }
8950
+ ]
8951
+ },
8952
+ "download-file-base64": {
8953
+ serviceClass: "Files",
8954
+ operationId: "downloadFileBase64",
8955
+ description: "Returns the file content encoded as base64",
8956
+ moduleDocsUrl: "https://docs.naturali.ai/docs/modules/files",
8957
+ httpMethod: "get",
8958
+ pathParams: ["project_id", "file_id"],
8959
+ queryParams: [],
8960
+ flags: [{
8961
+ "name": "project_id",
8962
+ "description": "Project public ID (proj_ prefix).",
8963
+ "required": true,
8964
+ "type": "string",
8965
+ "in": "path"
8966
+ }, {
8967
+ "name": "file_id",
8968
+ "description": "File ID",
8969
+ "required": true,
8970
+ "type": "string",
8971
+ "in": "path"
8972
+ }]
8973
+ },
8974
+ "get-file-tags": {
8975
+ serviceClass: "Files",
8976
+ operationId: "getFileTags",
8977
+ description: "Returns all tags attached to the file",
8978
+ moduleDocsUrl: "https://docs.naturali.ai/docs/modules/files",
8979
+ httpMethod: "get",
8980
+ pathParams: ["project_id", "file_id"],
8981
+ queryParams: [],
8982
+ flags: [{
8983
+ "name": "project_id",
8984
+ "description": "Project public ID (proj_ prefix).",
8985
+ "required": true,
8986
+ "type": "string",
8987
+ "in": "path"
8988
+ }, {
8989
+ "name": "file_id",
8990
+ "description": "File ID",
8991
+ "required": true,
8992
+ "type": "string",
8993
+ "in": "path"
8994
+ }]
8995
+ },
8996
+ "replace-file-tags": {
8997
+ serviceClass: "Files",
8998
+ operationId: "replaceFileTags",
8999
+ description: "Replaces all tags on the file with the provided tags",
9000
+ moduleDocsUrl: "https://docs.naturali.ai/docs/modules/files",
9001
+ httpMethod: "put",
9002
+ pathParams: ["project_id", "file_id"],
9003
+ queryParams: [],
9004
+ flags: [{
9005
+ "name": "project_id",
9006
+ "description": "Project public ID (proj_ prefix).",
9007
+ "required": true,
9008
+ "type": "string",
9009
+ "in": "path"
9010
+ }, {
9011
+ "name": "file_id",
9012
+ "description": "File ID",
9013
+ "required": true,
9014
+ "type": "string",
9015
+ "in": "path"
9016
+ }]
9017
+ },
9018
+ "merge-file-tags": {
9019
+ serviceClass: "Files",
9020
+ operationId: "mergeFileTags",
9021
+ description: "Merges provided tags with existing tags",
9022
+ moduleDocsUrl: "https://docs.naturali.ai/docs/modules/files",
9023
+ httpMethod: "patch",
9024
+ pathParams: ["project_id", "file_id"],
9025
+ queryParams: [],
9026
+ flags: [{
9027
+ "name": "project_id",
9028
+ "description": "Project public ID (proj_ prefix).",
9029
+ "required": true,
9030
+ "type": "string",
9031
+ "in": "path"
9032
+ }, {
9033
+ "name": "file_id",
9034
+ "description": "File ID",
9035
+ "required": true,
9036
+ "type": "string",
9037
+ "in": "path"
9038
+ }]
9039
+ },
9040
+ "list-generations": {
9041
+ serviceClass: "Generations",
9042
+ operationId: "listGenerations",
9043
+ description: "Returns generations the caller can access, optionally filtered by agent, trace, and status. Replaces the former per-trace generations endpoint (use the trace_id query filter).",
9044
+ moduleDocsUrl: "https://docs.naturali.ai/docs/modules/generations",
9045
+ httpMethod: "get",
9046
+ pathParams: ["project_id"],
9047
+ queryParams: [
9048
+ "agent_id",
9049
+ "trace_id",
9050
+ "initiator_generation_id",
9051
+ "status",
9052
+ "limit",
9053
+ "offset"
9054
+ ],
9055
+ flags: [
9056
+ {
9057
+ "name": "project_id",
9058
+ "description": "Project public ID (proj_ prefix).",
9059
+ "required": true,
9060
+ "type": "string",
9061
+ "in": "path"
9062
+ },
9063
+ {
9064
+ "name": "agent_id",
9065
+ "description": "Filter by agent public ID",
9066
+ "required": false,
9067
+ "type": "string",
9068
+ "in": "query"
9069
+ },
9070
+ {
9071
+ "name": "trace_id",
9072
+ "description": "Filter by trace public ID",
9073
+ "required": false,
9074
+ "type": "string",
9075
+ "in": "query"
9076
+ },
9077
+ {
9078
+ "name": "initiator_generation_id",
9079
+ "description": "Filter by the public ID of the parent generation. Returns all generations triggered by that generation — sub-agent invocations. Null-initiated (top-level) generations are not returned.\n",
9080
+ "required": false,
9081
+ "type": "string",
9082
+ "in": "query"
9083
+ },
9084
+ {
9085
+ "name": "status",
9086
+ "description": "Filter by lifecycle status",
9087
+ "required": false,
9088
+ "type": "string",
9089
+ "in": "query"
9090
+ },
9091
+ {
9092
+ "name": "limit",
9093
+ "description": "",
9094
+ "required": false,
9095
+ "type": "integer",
9096
+ "in": "query"
9097
+ },
9098
+ {
9099
+ "name": "offset",
9100
+ "description": "",
9101
+ "required": false,
9102
+ "type": "integer",
9103
+ "in": "query"
9104
+ }
9105
+ ]
9106
+ },
9107
+ "get-generation": {
9108
+ serviceClass: "Generations",
9109
+ operationId: "getGeneration",
9110
+ description: "Returns a single generation record by ID, including its status and the structured `error` payload when the generation failed (e.g. because the upstream AI provider returned an error).",
9111
+ moduleDocsUrl: "https://docs.naturali.ai/docs/modules/generations",
9112
+ httpMethod: "get",
9113
+ pathParams: ["project_id", "generation_id"],
9114
+ queryParams: [],
9115
+ flags: [{
9116
+ "name": "project_id",
9117
+ "description": "Project public ID (proj_ prefix).",
9118
+ "required": true,
9119
+ "type": "string",
9120
+ "in": "path"
9121
+ }, {
9122
+ "name": "generation_id",
9123
+ "description": "Public ID of the generation",
9124
+ "required": true,
9125
+ "type": "string",
9126
+ "in": "path"
9127
+ }]
9128
+ },
9129
+ "update-generation": {
9130
+ serviceClass: "Generations",
9131
+ operationId: "updateGeneration",
9132
+ description: "Attaches caller-supplied key/value metadata to a generation record for per-run audit attribution (e.g. recording which knowledge-corpus version produced an AI action). The provided keys are shallow-merged over the existing `metadata`, so repeated patches accumulate. The bag is caller-owned and no key is reserved: server-owned state (usage attribution, the served agent version, the route's record, the extraction summary) lives in its own top-level fields and cannot be written from here.",
9133
+ moduleDocsUrl: "https://docs.naturali.ai/docs/modules/generations",
9134
+ httpMethod: "patch",
9135
+ pathParams: ["project_id", "generation_id"],
9136
+ queryParams: [],
9137
+ flags: [
9138
+ {
9139
+ "name": "project_id",
9140
+ "description": "Project public ID (proj_ prefix).",
9141
+ "required": true,
9142
+ "type": "string",
9143
+ "in": "path"
9144
+ },
9145
+ {
9146
+ "name": "generation_id",
9147
+ "description": "Public ID of the generation",
9148
+ "required": true,
9149
+ "type": "string",
9150
+ "in": "path"
9151
+ },
9152
+ {
9153
+ "name": "metadata",
9154
+ "description": "Caller-supplied key/value metadata to shallow-merge into the generation record's caller-owned `metadata` bag. No key is reserved: server-owned state lives in its own top-level fields and cannot be written from here.\n",
9155
+ "required": true,
9156
+ "type": "object",
9157
+ "in": "body"
9158
+ }
9159
+ ]
9160
+ },
9161
+ "purge-generation-content": {
9162
+ serviceClass: "Generations",
9163
+ operationId: "purgeGenerationContent",
9164
+ description: "Clears the generation's content — `metadata`, `error`, `extraction`, and the internal recovery state of a paused run — and stamps `content_redacted_at`. The usage and audit skeleton is preserved: ids, timestamps, status, stop reason, and the attribution fields (`action_id`, `trigger_id`, `orchestration_run_id`, `node_id`, `agent_version`, `routing`) the billing ledger reads. A purged generation reads back as that skeleton, not a 404. This does **not** delete the parent trace's steps object, which holds this generation's content alongside its siblings'. To erase the run's content completely, purge the trace (`DELETE /v1/projects/{project_id}/traces/{trace_id}/content`), which cascades here. Idempotent — purging an already-purged generation succeeds and leaves the original `content_redacted_at` in place.",
9165
+ moduleDocsUrl: "https://docs.naturali.ai/docs/modules/generations",
9166
+ httpMethod: "delete",
9167
+ pathParams: ["project_id", "generation_id"],
9168
+ queryParams: [],
9169
+ flags: [{
9170
+ "name": "project_id",
9171
+ "description": "Project public ID (proj_ prefix).",
9172
+ "required": true,
9173
+ "type": "string",
9174
+ "in": "path"
9175
+ }, {
9176
+ "name": "generation_id",
9177
+ "description": "Public ID of the generation",
9178
+ "required": true,
9179
+ "type": "string",
9180
+ "in": "path"
9181
+ }]
9182
+ },
9183
+ "get-generation-transcript": {
9184
+ serviceClass: "Generations",
9185
+ operationId: "getGenerationTranscript",
9186
+ description: "Returns one generation's turn read back as an ordered sequence of steps: what it was asked, each model step with its tool calls and results, and how it ended. The transcript is assembled at read time from the generation record and the trace's steps object; nothing is stored, so it cannot outlive the content it projects. Requires `traces:GetTrace` in addition to `generations:GetGeneration`, because the response merges content from both resources. A generation whose content is unavailable — never written under zero-retention, or cleared by a purge — returns `200` with the skeleton rather than an error: `input` and `output` are null, `steps` is empty, and the `content_redacted_*` fields say which happened. `content_redacted_by_principal_id` is `zero_retention` when the content was never stored, and the purging principal's ID when it was erased later. A generation that is still running returns the same shape with an empty `steps`; `status` disambiguates the two.",
9187
+ moduleDocsUrl: "https://docs.naturali.ai/docs/modules/generations",
9188
+ httpMethod: "get",
9189
+ pathParams: ["project_id", "generation_id"],
7832
9190
  queryParams: [],
7833
9191
  flags: [{
7834
9192
  "name": "project_id",
@@ -7844,14 +9202,14 @@ const routes = {
7844
9202
  "in": "path"
7845
9203
  }]
7846
9204
  },
7847
- "update-generation": {
7848
- serviceClass: "Generations",
7849
- operationId: "updateGeneration",
7850
- description: "Attaches caller-supplied key/value metadata to a generation record for per-run audit attribution (e.g. recording which knowledge-corpus version produced an AI action). The provided keys are shallow-merged over the existing `metadata`, so repeated patches accumulate. The bag is caller-owned and no key is reserved: server-owned state (usage attribution, the served agent version, the route's record, the extraction summary) lives in its own top-level fields and cannot be written from here.",
7851
- moduleDocsUrl: "https://docs.naturali.ai/docs/modules/generations",
7852
- httpMethod: "patch",
7853
- pathParams: ["project_id", "generation_id"],
7854
- queryParams: [],
9205
+ "list-ingestion-rules": {
9206
+ serviceClass: "IngestionRules",
9207
+ operationId: "listIngestionRules",
9208
+ description: "Returns the ingestion rules for a project",
9209
+ moduleDocsUrl: "https://docs.naturali.ai/docs/modules/ingestion-rules",
9210
+ httpMethod: "get",
9211
+ pathParams: ["project_id"],
9212
+ queryParams: ["limit", "offset"],
7855
9213
  flags: [
7856
9214
  {
7857
9215
  "name": "project_id",
@@ -7861,28 +9219,123 @@ const routes = {
7861
9219
  "in": "path"
7862
9220
  },
7863
9221
  {
7864
- "name": "generation_id",
7865
- "description": "Public ID of the generation",
9222
+ "name": "limit",
9223
+ "description": "Number of results per page",
9224
+ "required": false,
9225
+ "type": "integer",
9226
+ "in": "query"
9227
+ },
9228
+ {
9229
+ "name": "offset",
9230
+ "description": "Number of results to skip",
9231
+ "required": false,
9232
+ "type": "integer",
9233
+ "in": "query"
9234
+ }
9235
+ ]
9236
+ },
9237
+ "create-ingestion-rule": {
9238
+ serviceClass: "IngestionRules",
9239
+ operationId: "createIngestionRule",
9240
+ description: "Creates a rule mapping a content_type glob to a converter. Exactly one of tool_id or agent_id must be set.",
9241
+ moduleDocsUrl: "https://docs.naturali.ai/docs/modules/ingestion-rules",
9242
+ httpMethod: "post",
9243
+ pathParams: ["project_id"],
9244
+ queryParams: [],
9245
+ flags: [
9246
+ {
9247
+ "name": "project_id",
9248
+ "description": "Project public ID (proj_ prefix).",
7866
9249
  "required": true,
7867
9250
  "type": "string",
7868
9251
  "in": "path"
7869
9252
  },
7870
9253
  {
7871
- "name": "metadata",
7872
- "description": "Caller-supplied key/value metadata to shallow-merge into the generation record's caller-owned `metadata` bag. No key is reserved: server-owned state lives in its own top-level fields and cannot be written from here.\n",
9254
+ "name": "content_type_glob",
9255
+ "description": "MIME type glob matched against a file's content_type",
7873
9256
  "required": true,
9257
+ "type": "string",
9258
+ "in": "body"
9259
+ },
9260
+ {
9261
+ "name": "tool_id",
9262
+ "description": "Converter tool id (mutually exclusive with agent_id)",
9263
+ "required": false,
9264
+ "type": "string",
9265
+ "in": "body"
9266
+ },
9267
+ {
9268
+ "name": "agent_id",
9269
+ "description": "Converter agent id (mutually exclusive with tool_id)",
9270
+ "required": false,
9271
+ "type": "string",
9272
+ "in": "body"
9273
+ },
9274
+ {
9275
+ "name": "action",
9276
+ "description": "Operation id, required for mcp tool converters",
9277
+ "required": false,
9278
+ "type": "string",
9279
+ "in": "body"
9280
+ },
9281
+ {
9282
+ "name": "preset_parameters",
9283
+ "description": "Merged into the tool input before invocation (tool converters only)",
9284
+ "required": false,
9285
+ "type": "object",
9286
+ "in": "body"
9287
+ },
9288
+ {
9289
+ "name": "native_extraction",
9290
+ "description": "For native types (PDF/text): `first` (default) converts only when native extraction yields no text; `skip` always converts.",
9291
+ "required": false,
9292
+ "type": "string",
9293
+ "in": "body"
9294
+ },
9295
+ {
9296
+ "name": "file_delivery",
9297
+ "description": "How the file reaches a tool converter (default base64)",
9298
+ "required": false,
9299
+ "type": "string",
9300
+ "in": "body"
9301
+ },
9302
+ {
9303
+ "name": "chunk_strategy",
9304
+ "description": "Default chunk strategy, overridable per ingest request",
9305
+ "required": false,
9306
+ "type": "string",
9307
+ "in": "body"
9308
+ },
9309
+ {
9310
+ "name": "chunk_size",
9311
+ "description": "Default window size in characters for the size strategy",
9312
+ "required": false,
9313
+ "type": "integer",
9314
+ "in": "body"
9315
+ },
9316
+ {
9317
+ "name": "chunk_overlap",
9318
+ "description": "Default overlap in characters for the size strategy",
9319
+ "required": false,
9320
+ "type": "integer",
9321
+ "in": "body"
9322
+ },
9323
+ {
9324
+ "name": "metadata",
9325
+ "description": "Arbitrary JSON metadata",
9326
+ "required": false,
7874
9327
  "type": "object",
7875
9328
  "in": "body"
7876
9329
  }
7877
9330
  ]
7878
9331
  },
7879
- "purge-generation-content": {
7880
- serviceClass: "Generations",
7881
- operationId: "purgeGenerationContent",
7882
- description: "Clears the generation's content — `metadata`, `error`, `extraction`, and the internal recovery state of a paused run — and stamps `content_redacted_at`. The usage and audit skeleton is preserved: ids, timestamps, status, stop reason, and the attribution fields (`action_id`, `trigger_id`, `orchestration_run_id`, `node_id`, `agent_version`, `routing`) the billing ledger reads. A purged generation reads back as that skeleton, not a 404. This does **not** delete the parent trace's steps object, which holds this generation's content alongside its siblings'. To erase the run's content completely, purge the trace (`DELETE /v1/projects/{project_id}/traces/{trace_id}/content`), which cascades here. Idempotent — purging an already-purged generation succeeds and leaves the original `content_redacted_at` in place.",
7883
- moduleDocsUrl: "https://docs.naturali.ai/docs/modules/generations",
7884
- httpMethod: "delete",
7885
- pathParams: ["project_id", "generation_id"],
9332
+ "get-ingestion-rule": {
9333
+ serviceClass: "IngestionRules",
9334
+ operationId: "getIngestionRule",
9335
+ description: "Returns a specific ingestion rule",
9336
+ moduleDocsUrl: "https://docs.naturali.ai/docs/modules/ingestion-rules",
9337
+ httpMethod: "get",
9338
+ pathParams: ["project_id", "ingestion_rule_id"],
7886
9339
  queryParams: [],
7887
9340
  flags: [{
7888
9341
  "name": "project_id",
@@ -7891,20 +9344,122 @@ const routes = {
7891
9344
  "type": "string",
7892
9345
  "in": "path"
7893
9346
  }, {
7894
- "name": "generation_id",
7895
- "description": "Public ID of the generation",
9347
+ "name": "ingestion_rule_id",
9348
+ "description": "Ingestion rule ID",
7896
9349
  "required": true,
7897
9350
  "type": "string",
7898
9351
  "in": "path"
7899
9352
  }]
7900
9353
  },
7901
- "get-generation-transcript": {
7902
- serviceClass: "Generations",
7903
- operationId: "getGenerationTranscript",
7904
- description: "Returns one generation's turn read back as an ordered sequence of steps: what it was asked, each model step with its tool calls and results, and how it ended. The transcript is assembled at read time from the generation record and the trace's steps object; nothing is stored, so it cannot outlive the content it projects. Requires `traces:GetTrace` in addition to `generations:GetGeneration`, because the response merges content from both resources. A generation whose content is unavailable — never written under zero-retention, or cleared by a purge — returns `200` with the skeleton rather than an error: `input` and `output` are null, `steps` is empty, and the `content_redacted_*` fields say which happened. `content_redacted_by_principal_id` is `zero_retention` when the content was never stored, and the purging principal's ID when it was erased later. A generation that is still running returns the same shape with an empty `steps`; `status` disambiguates the two.",
7905
- moduleDocsUrl: "https://docs.naturali.ai/docs/modules/generations",
7906
- httpMethod: "get",
7907
- pathParams: ["project_id", "generation_id"],
9354
+ "update-ingestion-rule": {
9355
+ serviceClass: "IngestionRules",
9356
+ operationId: "updateIngestionRule",
9357
+ description: "Updates fields of an ingestion rule",
9358
+ moduleDocsUrl: "https://docs.naturali.ai/docs/modules/ingestion-rules",
9359
+ httpMethod: "patch",
9360
+ pathParams: ["project_id", "ingestion_rule_id"],
9361
+ queryParams: [],
9362
+ flags: [
9363
+ {
9364
+ "name": "project_id",
9365
+ "description": "Project public ID (proj_ prefix).",
9366
+ "required": true,
9367
+ "type": "string",
9368
+ "in": "path"
9369
+ },
9370
+ {
9371
+ "name": "ingestion_rule_id",
9372
+ "description": "Ingestion rule ID",
9373
+ "required": true,
9374
+ "type": "string",
9375
+ "in": "path"
9376
+ },
9377
+ {
9378
+ "name": "content_type_glob",
9379
+ "description": "",
9380
+ "required": false,
9381
+ "type": "string",
9382
+ "in": "body"
9383
+ },
9384
+ {
9385
+ "name": "tool_id",
9386
+ "description": "",
9387
+ "required": false,
9388
+ "type": "string",
9389
+ "in": "body"
9390
+ },
9391
+ {
9392
+ "name": "agent_id",
9393
+ "description": "",
9394
+ "required": false,
9395
+ "type": "string",
9396
+ "in": "body"
9397
+ },
9398
+ {
9399
+ "name": "action",
9400
+ "description": "",
9401
+ "required": false,
9402
+ "type": "string",
9403
+ "in": "body"
9404
+ },
9405
+ {
9406
+ "name": "preset_parameters",
9407
+ "description": "",
9408
+ "required": false,
9409
+ "type": "object",
9410
+ "in": "body"
9411
+ },
9412
+ {
9413
+ "name": "native_extraction",
9414
+ "description": "",
9415
+ "required": false,
9416
+ "type": "string",
9417
+ "in": "body"
9418
+ },
9419
+ {
9420
+ "name": "file_delivery",
9421
+ "description": "",
9422
+ "required": false,
9423
+ "type": "string",
9424
+ "in": "body"
9425
+ },
9426
+ {
9427
+ "name": "chunk_strategy",
9428
+ "description": "Send `null` to clear the rule's override and fall back to the per-request default.",
9429
+ "required": false,
9430
+ "type": "string",
9431
+ "in": "body"
9432
+ },
9433
+ {
9434
+ "name": "chunk_size",
9435
+ "description": "",
9436
+ "required": false,
9437
+ "type": "integer",
9438
+ "in": "body"
9439
+ },
9440
+ {
9441
+ "name": "chunk_overlap",
9442
+ "description": "",
9443
+ "required": false,
9444
+ "type": "integer",
9445
+ "in": "body"
9446
+ },
9447
+ {
9448
+ "name": "metadata",
9449
+ "description": "",
9450
+ "required": false,
9451
+ "type": "object",
9452
+ "in": "body"
9453
+ }
9454
+ ]
9455
+ },
9456
+ "delete-ingestion-rule": {
9457
+ serviceClass: "IngestionRules",
9458
+ operationId: "deleteIngestionRule",
9459
+ description: "Deletes an ingestion rule",
9460
+ moduleDocsUrl: "https://docs.naturali.ai/docs/modules/ingestion-rules",
9461
+ httpMethod: "delete",
9462
+ pathParams: ["project_id", "ingestion_rule_id"],
7908
9463
  queryParams: [],
7909
9464
  flags: [{
7910
9465
  "name": "project_id",
@@ -7913,13 +9468,80 @@ const routes = {
7913
9468
  "type": "string",
7914
9469
  "in": "path"
7915
9470
  }, {
7916
- "name": "generation_id",
7917
- "description": "Public ID of the generation",
9471
+ "name": "ingestion_rule_id",
9472
+ "description": "Ingestion rule ID",
7918
9473
  "required": true,
7919
9474
  "type": "string",
7920
9475
  "in": "path"
7921
9476
  }]
7922
9477
  },
9478
+ "search-knowledge": {
9479
+ serviceClass: "Knowledge",
9480
+ operationId: "searchKnowledge",
9481
+ description: "Searches across documents and memory entries using semantic search, file paths, document IDs, or memory IDs/tags. At least one of `query`, `document_paths`, `document_ids`, `memory_ids`, or `memory_tags` must be provided.",
9482
+ moduleDocsUrl: "https://docs.naturali.ai/docs/modules/knowledge",
9483
+ httpMethod: "post",
9484
+ pathParams: ["project_id"],
9485
+ queryParams: [],
9486
+ flags: [
9487
+ {
9488
+ "name": "project_id",
9489
+ "description": "Project public ID (proj_ prefix).",
9490
+ "required": true,
9491
+ "type": "string",
9492
+ "in": "path"
9493
+ },
9494
+ {
9495
+ "name": "query",
9496
+ "description": "Semantic search query text",
9497
+ "required": false,
9498
+ "type": "string",
9499
+ "in": "body"
9500
+ },
9501
+ {
9502
+ "name": "min_score",
9503
+ "description": "Minimum `score` a result must reach to be returned. Filters on the implementation-defined `score`, not on `similarity_score`, so the cutoff follows the ranking. Only applies when `query` is provided. Because the scale behind `score` is not part of the contract, treat a tuned value as tied to the deployment rather than portable.",
9504
+ "required": false,
9505
+ "type": "number",
9506
+ "in": "body"
9507
+ },
9508
+ {
9509
+ "name": "limit",
9510
+ "description": "Maximum number of results to return (default 10)",
9511
+ "required": false,
9512
+ "type": "integer",
9513
+ "in": "body"
9514
+ },
9515
+ {
9516
+ "name": "memory_ids",
9517
+ "description": "Search entries within these specific memories",
9518
+ "required": false,
9519
+ "type": "array",
9520
+ "in": "body"
9521
+ },
9522
+ {
9523
+ "name": "memory_tags",
9524
+ "description": "Search entries in memories whose tags match any of these patterns (glob supported)",
9525
+ "required": false,
9526
+ "type": "array",
9527
+ "in": "body"
9528
+ },
9529
+ {
9530
+ "name": "document_paths",
9531
+ "description": "Filter results to documents whose file path starts with one of these prefixes",
9532
+ "required": false,
9533
+ "type": "array",
9534
+ "in": "body"
9535
+ },
9536
+ {
9537
+ "name": "document_ids",
9538
+ "description": "Filter results to specific document IDs",
9539
+ "required": false,
9540
+ "type": "array",
9541
+ "in": "body"
9542
+ }
9543
+ ]
9544
+ },
7923
9545
  "list-model-routes": {
7924
9546
  serviceClass: "ModelRoutes",
7925
9547
  operationId: "listModelRoutes",