@naturali/cli 0.28.0 → 0.28.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -0
- package/dist/index.mjs +87 -72
- package/package.json +5 -3
package/README.md
CHANGED
|
@@ -88,6 +88,19 @@ pipeline.
|
|
|
88
88
|
Hand-written source is limited to dispatch, flag parsing, credentials and help;
|
|
89
89
|
there is no per-endpoint code.
|
|
90
90
|
|
|
91
|
+
## Testing
|
|
92
|
+
|
|
93
|
+
`pnpm test` runs the unit suite against a mocked `fetch` — flag parsing,
|
|
94
|
+
dispatch, and help output, on every pull request.
|
|
95
|
+
|
|
96
|
+
`pnpm e2e` (`tests/e2e/smoke.ts`) is different: it drives the *built* CLI
|
|
97
|
+
binary (`bin/naturali`) as real subprocesses against the real, deployed API,
|
|
98
|
+
using a `NATURALI_E2E_API_KEY` account-scoped key. It proves the one thing the
|
|
99
|
+
mocked suite can't — that the CLI, the `@naturali/sdk` it bundles, and the live
|
|
100
|
+
API actually agree — and it provisions and archives its own throwaway project.
|
|
101
|
+
It costs real model-provider money, so it only runs as part of the `e2e` job in
|
|
102
|
+
[`main.yml`](../../.github/workflows/main.yml), never on pull requests.
|
|
103
|
+
|
|
91
104
|
## Versioning
|
|
92
105
|
|
|
93
106
|
Releases are automatic, and the version is **shared with the API and with
|
package/dist/index.mjs
CHANGED
|
@@ -14,7 +14,7 @@ var __exportAll = (all, no_symbols) => {
|
|
|
14
14
|
};
|
|
15
15
|
//#endregion
|
|
16
16
|
//#region package.json
|
|
17
|
-
var version = "0.28.
|
|
17
|
+
var version = "0.28.2";
|
|
18
18
|
//#endregion
|
|
19
19
|
//#region ../sdk/src/generated/core/bodySerializer.gen.ts
|
|
20
20
|
const jsonBodySerializer = { bodySerializer: (body) => JSON.stringify(body, (_key, value) => typeof value === "bigint" ? value.toString() : value) };
|
|
@@ -1299,7 +1299,7 @@ var Knowledge = class {
|
|
|
1299
1299
|
*/
|
|
1300
1300
|
static queryKnowledgeCollection(options) {
|
|
1301
1301
|
return (options.client ?? client).post({
|
|
1302
|
-
url: "/v1/projects/{project_id}/knowledge/collections/{collection_id}",
|
|
1302
|
+
url: "/v1/projects/{project_id}/knowledge/collections/{collection_id}:query",
|
|
1303
1303
|
...options,
|
|
1304
1304
|
headers: {
|
|
1305
1305
|
"Content-Type": "application/json",
|
|
@@ -1362,7 +1362,7 @@ var Knowledge = class {
|
|
|
1362
1362
|
*/
|
|
1363
1363
|
static reingestKnowledgeDocument(options) {
|
|
1364
1364
|
return (options.client ?? client).post({
|
|
1365
|
-
url: "/v1/projects/{project_id}/knowledge/collections/{collection_id}/documents/{document_id}",
|
|
1365
|
+
url: "/v1/projects/{project_id}/knowledge/collections/{collection_id}/documents/{document_id}:reingest",
|
|
1366
1366
|
...options
|
|
1367
1367
|
});
|
|
1368
1368
|
}
|
|
@@ -2107,6 +2107,32 @@ const formatError = (args) => {
|
|
|
2107
2107
|
}, null, 2);
|
|
2108
2108
|
};
|
|
2109
2109
|
/**
|
|
2110
|
+
* Resolves the generated SDK method for a route, exiting with an error
|
|
2111
|
+
* envelope if the service class or the method itself cannot be found.
|
|
2112
|
+
*/
|
|
2113
|
+
const resolveServiceMethod = (route) => {
|
|
2114
|
+
const serviceClass = resolveServiceClass(route.serviceClass);
|
|
2115
|
+
if (!serviceClass) {
|
|
2116
|
+
console.error(`SDK class "${route.serviceClass}" not found.`);
|
|
2117
|
+
process.exit(1);
|
|
2118
|
+
}
|
|
2119
|
+
const method = serviceClass[route.operationId];
|
|
2120
|
+
if (typeof method !== "function") {
|
|
2121
|
+
console.error(`Method "${route.operationId}" not found on ${route.serviceClass}.`);
|
|
2122
|
+
process.exit(1);
|
|
2123
|
+
}
|
|
2124
|
+
return method;
|
|
2125
|
+
};
|
|
2126
|
+
/** Builds the SDK call options from a resolved route call, omitting empty parts. */
|
|
2127
|
+
const buildCallOptions = (args) => {
|
|
2128
|
+
const { client, call } = args;
|
|
2129
|
+
const callOptions = { client };
|
|
2130
|
+
if (Object.keys(call.path).length) callOptions["path"] = call.path;
|
|
2131
|
+
if (Object.keys(call.query).length) callOptions["query"] = call.query;
|
|
2132
|
+
if (Object.keys(call.body).length) callOptions["body"] = call.body;
|
|
2133
|
+
return callOptions;
|
|
2134
|
+
};
|
|
2135
|
+
/**
|
|
2110
2136
|
* Runs one generated command: parses its flags, resolves credentials, calls the
|
|
2111
2137
|
* matching SDK method, and prints the result.
|
|
2112
2138
|
*
|
|
@@ -2135,21 +2161,10 @@ const dispatchCommand = async (args) => {
|
|
|
2135
2161
|
console.error(`Missing required path parameter(s): ${built.missingPathParams.join(", ")}.\nProvide with ${flagsHint}.`);
|
|
2136
2162
|
process.exit(1);
|
|
2137
2163
|
}
|
|
2138
|
-
const
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
}
|
|
2143
|
-
const method = serviceClass[route.operationId];
|
|
2144
|
-
if (typeof method !== "function") {
|
|
2145
|
-
console.error(`Method "${route.operationId}" not found on ${route.serviceClass}.`);
|
|
2146
|
-
process.exit(1);
|
|
2147
|
-
}
|
|
2148
|
-
const callOptions = { client: context.client };
|
|
2149
|
-
if (Object.keys(built.call.path).length) callOptions["path"] = built.call.path;
|
|
2150
|
-
if (Object.keys(built.call.query).length) callOptions["query"] = built.call.query;
|
|
2151
|
-
if (Object.keys(built.call.body).length) callOptions["body"] = built.call.body;
|
|
2152
|
-
const result = await method(callOptions) ?? {};
|
|
2164
|
+
const result = await resolveServiceMethod(route)(buildCallOptions({
|
|
2165
|
+
client: context.client,
|
|
2166
|
+
call: built.call
|
|
2167
|
+
})) ?? {};
|
|
2153
2168
|
if (result.error) {
|
|
2154
2169
|
console.error(formatError({
|
|
2155
2170
|
error: result.error,
|
|
@@ -3779,52 +3794,6 @@ const routes = {
|
|
|
3779
3794
|
"in": "path"
|
|
3780
3795
|
}]
|
|
3781
3796
|
},
|
|
3782
|
-
"query-knowledge-collection": {
|
|
3783
|
-
serviceClass: "Knowledge",
|
|
3784
|
-
operationId: "queryKnowledgeCollection",
|
|
3785
|
-
description: "Retrieval preview (API.md §4, K5): returns the chunks the collection would surface for a question — debuggable standalone, before any agent is bound to it. This is the `…:query` action; the path segment is `{collection_id}:query`.",
|
|
3786
|
-
moduleDocsUrl: "https://docs.naturali.ai/docs/modules/knowledge",
|
|
3787
|
-
httpMethod: "post",
|
|
3788
|
-
pathParams: ["project_id", "collection_id"],
|
|
3789
|
-
queryParams: [],
|
|
3790
|
-
flags: [
|
|
3791
|
-
{
|
|
3792
|
-
"name": "project_id",
|
|
3793
|
-
"description": "Project public ID (proj_ prefix).",
|
|
3794
|
-
"required": true,
|
|
3795
|
-
"type": "string",
|
|
3796
|
-
"in": "path"
|
|
3797
|
-
},
|
|
3798
|
-
{
|
|
3799
|
-
"name": "collection_id",
|
|
3800
|
-
"description": "Knowledge collection public ID (kcol_ prefix).",
|
|
3801
|
-
"required": true,
|
|
3802
|
-
"type": "string",
|
|
3803
|
-
"in": "path"
|
|
3804
|
-
},
|
|
3805
|
-
{
|
|
3806
|
-
"name": "query",
|
|
3807
|
-
"description": "The question to preview retrieval for.",
|
|
3808
|
-
"required": true,
|
|
3809
|
-
"type": "string",
|
|
3810
|
-
"in": "body"
|
|
3811
|
-
},
|
|
3812
|
-
{
|
|
3813
|
-
"name": "top_k",
|
|
3814
|
-
"description": "Maximum chunks to return.",
|
|
3815
|
-
"required": false,
|
|
3816
|
-
"type": "integer",
|
|
3817
|
-
"in": "body"
|
|
3818
|
-
},
|
|
3819
|
-
{
|
|
3820
|
-
"name": "min_score",
|
|
3821
|
-
"description": "Drop chunks below this similarity score.",
|
|
3822
|
-
"required": false,
|
|
3823
|
-
"type": "number",
|
|
3824
|
-
"in": "body"
|
|
3825
|
-
}
|
|
3826
|
-
]
|
|
3827
|
-
},
|
|
3828
3797
|
"update-knowledge-collection": {
|
|
3829
3798
|
serviceClass: "Knowledge",
|
|
3830
3799
|
operationId: "updateKnowledgeCollection",
|
|
@@ -3886,6 +3855,52 @@ const routes = {
|
|
|
3886
3855
|
"in": "path"
|
|
3887
3856
|
}]
|
|
3888
3857
|
},
|
|
3858
|
+
"query-knowledge-collection": {
|
|
3859
|
+
serviceClass: "Knowledge",
|
|
3860
|
+
operationId: "queryKnowledgeCollection",
|
|
3861
|
+
description: "Retrieval preview (API.md §4, K5): returns the chunks the collection would surface for a question — debuggable standalone, before any agent is bound to it. This is the `…:query` action; the path segment is `{collection_id}:query`.",
|
|
3862
|
+
moduleDocsUrl: "https://docs.naturali.ai/docs/modules/knowledge",
|
|
3863
|
+
httpMethod: "post",
|
|
3864
|
+
pathParams: ["project_id", "collection_id"],
|
|
3865
|
+
queryParams: [],
|
|
3866
|
+
flags: [
|
|
3867
|
+
{
|
|
3868
|
+
"name": "project_id",
|
|
3869
|
+
"description": "Project public ID (proj_ prefix).",
|
|
3870
|
+
"required": true,
|
|
3871
|
+
"type": "string",
|
|
3872
|
+
"in": "path"
|
|
3873
|
+
},
|
|
3874
|
+
{
|
|
3875
|
+
"name": "collection_id",
|
|
3876
|
+
"description": "Knowledge collection public ID (kcol_ prefix).",
|
|
3877
|
+
"required": true,
|
|
3878
|
+
"type": "string",
|
|
3879
|
+
"in": "path"
|
|
3880
|
+
},
|
|
3881
|
+
{
|
|
3882
|
+
"name": "query",
|
|
3883
|
+
"description": "The question to preview retrieval for.",
|
|
3884
|
+
"required": true,
|
|
3885
|
+
"type": "string",
|
|
3886
|
+
"in": "body"
|
|
3887
|
+
},
|
|
3888
|
+
{
|
|
3889
|
+
"name": "top_k",
|
|
3890
|
+
"description": "Maximum chunks to return.",
|
|
3891
|
+
"required": false,
|
|
3892
|
+
"type": "integer",
|
|
3893
|
+
"in": "body"
|
|
3894
|
+
},
|
|
3895
|
+
{
|
|
3896
|
+
"name": "min_score",
|
|
3897
|
+
"description": "Drop chunks below this similarity score.",
|
|
3898
|
+
"required": false,
|
|
3899
|
+
"type": "number",
|
|
3900
|
+
"in": "body"
|
|
3901
|
+
}
|
|
3902
|
+
]
|
|
3903
|
+
},
|
|
3889
3904
|
"list-knowledge-documents": {
|
|
3890
3905
|
serviceClass: "Knowledge",
|
|
3891
3906
|
operationId: "listKnowledgeDocuments",
|
|
@@ -4007,12 +4022,12 @@ const routes = {
|
|
|
4007
4022
|
}
|
|
4008
4023
|
]
|
|
4009
4024
|
},
|
|
4010
|
-
"
|
|
4025
|
+
"delete-knowledge-document": {
|
|
4011
4026
|
serviceClass: "Knowledge",
|
|
4012
|
-
operationId: "
|
|
4013
|
-
description: "
|
|
4027
|
+
operationId: "deleteKnowledgeDocument",
|
|
4028
|
+
description: "Delete a document",
|
|
4014
4029
|
moduleDocsUrl: "https://docs.naturali.ai/docs/modules/knowledge",
|
|
4015
|
-
httpMethod: "
|
|
4030
|
+
httpMethod: "delete",
|
|
4016
4031
|
pathParams: [
|
|
4017
4032
|
"project_id",
|
|
4018
4033
|
"collection_id",
|
|
@@ -4043,12 +4058,12 @@ const routes = {
|
|
|
4043
4058
|
}
|
|
4044
4059
|
]
|
|
4045
4060
|
},
|
|
4046
|
-
"
|
|
4061
|
+
"reingest-knowledge-document": {
|
|
4047
4062
|
serviceClass: "Knowledge",
|
|
4048
|
-
operationId: "
|
|
4049
|
-
description: "
|
|
4063
|
+
operationId: "reingestKnowledgeDocument",
|
|
4064
|
+
description: "Re-run ingestion for a document against its stored source, resetting it to `pending` before re-processing — the recovery path for a `failed` ingest (API.md §4, K1). This is the `…:reingest` action; the path segment is `{document_id}:reingest`.",
|
|
4050
4065
|
moduleDocsUrl: "https://docs.naturali.ai/docs/modules/knowledge",
|
|
4051
|
-
httpMethod: "
|
|
4066
|
+
httpMethod: "post",
|
|
4052
4067
|
pathParams: [
|
|
4053
4068
|
"project_id",
|
|
4054
4069
|
"collection_id",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@naturali/cli",
|
|
3
|
-
"version": "0.28.
|
|
3
|
+
"version": "0.28.2",
|
|
4
4
|
"description": "Command-line interface for the naturali.ai API, generated from its OpenAPI specs",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -30,12 +30,14 @@
|
|
|
30
30
|
"tsx": "^4.23.1",
|
|
31
31
|
"typescript": "~6.0.3",
|
|
32
32
|
"vitest": "^4.1.10",
|
|
33
|
-
"@naturali/sdk": "0.28.
|
|
33
|
+
"@naturali/sdk": "0.28.2"
|
|
34
34
|
},
|
|
35
35
|
"scripts": {
|
|
36
36
|
"generate": "tsx scripts/generate.ts",
|
|
37
37
|
"typecheck": "tsc --noEmit",
|
|
38
|
+
"lint": "eslint src tests",
|
|
38
39
|
"test": "vitest run",
|
|
39
|
-
"build": "tsdown"
|
|
40
|
+
"build": "tsdown",
|
|
41
|
+
"e2e": "tsx tests/e2e/smoke.ts"
|
|
40
42
|
}
|
|
41
43
|
}
|