@kweaver-ai/kweaver-sdk 0.4.12 → 0.4.13
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 +27 -2
- package/README.zh.md +27 -2
- package/dist/api/dataflow.d.ts +2 -0
- package/dist/api/dataflow.js +5 -3
- package/dist/api/dataviews.d.ts +41 -1
- package/dist/api/dataviews.js +58 -5
- package/dist/api/vega.js +1 -1
- package/dist/auth/oauth.d.ts +21 -0
- package/dist/auth/oauth.js +226 -54
- package/dist/cli.js +5 -2
- package/dist/commands/agent.js +15 -15
- package/dist/commands/auth.js +80 -6
- package/dist/commands/bkn.d.ts +11 -0
- package/dist/commands/bkn.js +90 -55
- package/dist/commands/dataview.js +61 -2
- package/dist/commands/vega.js +7 -7
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/resources/dataviews.d.ts +10 -1
- package/dist/resources/dataviews.js +14 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -18,6 +18,8 @@ Usage:
|
|
|
18
18
|
|
|
19
19
|
kweaver auth <platform-url> [--alias name] [-u user] [-p pass] [--playwright] [--insecure|-k]
|
|
20
20
|
kweaver auth login <platform-url> (alias for auth <url>)
|
|
21
|
+
kweaver auth login <url> --client-id ID --client-secret S --refresh-token T (run on host without browser)
|
|
22
|
+
kweaver auth export [platform-url|alias] [--json]
|
|
21
23
|
kweaver auth status [platform-url|alias]
|
|
22
24
|
kweaver auth list
|
|
23
25
|
kweaver auth use <platform-url|alias>
|
|
@@ -51,6 +53,7 @@ Usage:
|
|
|
51
53
|
kweaver dataview list [--datasource-id id] [--type atomic|custom] [--limit n] [-bd value] [--pretty]
|
|
52
54
|
kweaver dataview find --name <name> [--exact] [--datasource-id id] [--wait] [--timeout ms] [-bd value] [--pretty]
|
|
53
55
|
kweaver dataview get <id> [-bd value] [--pretty]
|
|
56
|
+
kweaver dataview query <id> [--sql sql] [--limit n] [--offset n] [--need-total] [-bd value] [--pretty]
|
|
54
57
|
kweaver dataview delete <id> [-y] [-bd value]
|
|
55
58
|
|
|
56
59
|
kweaver bkn list [options]
|
|
@@ -96,7 +99,7 @@ Commands:
|
|
|
96
99
|
call (curl) Call an API with curl-style flags and auto-injected token headers
|
|
97
100
|
agent Agent CRUD, chat, sessions, history, publish/unpublish
|
|
98
101
|
ds Manage datasources (list, get, delete, tables, connect)
|
|
99
|
-
dataview
|
|
102
|
+
dataview|dv List, find, get, query (SQL), delete data views (atomic / custom)
|
|
100
103
|
bkn Knowledge network (CRUD, build, validate, export, stats, push/pull,
|
|
101
104
|
object-type, relation-type, subgraph, action-type, action-execution, action-log)
|
|
102
105
|
config Per-platform configuration (business domain)
|
|
@@ -127,7 +130,7 @@ export async function run(argv) {
|
|
|
127
130
|
if (command === "ds") {
|
|
128
131
|
return runDsCommand(rest);
|
|
129
132
|
}
|
|
130
|
-
if (command === "dataview") {
|
|
133
|
+
if (command === "dataview" || command === "dv") {
|
|
131
134
|
return runDataviewCommand(rest);
|
|
132
135
|
}
|
|
133
136
|
if (command === "token") {
|
package/dist/commands/agent.js
CHANGED
|
@@ -45,7 +45,7 @@ export function formatSimpleAgentList(text, pretty) {
|
|
|
45
45
|
export function parseAgentListArgs(args) {
|
|
46
46
|
let name = "";
|
|
47
47
|
let offset = 0;
|
|
48
|
-
let limit =
|
|
48
|
+
let limit = 30;
|
|
49
49
|
let category_id = "";
|
|
50
50
|
let custom_space_id = "";
|
|
51
51
|
let is_to_square = 1;
|
|
@@ -70,9 +70,9 @@ export function parseAgentListArgs(args) {
|
|
|
70
70
|
continue;
|
|
71
71
|
}
|
|
72
72
|
if (arg === "--limit") {
|
|
73
|
-
limit = parseInt(args[i + 1] ?? "
|
|
73
|
+
limit = parseInt(args[i + 1] ?? "30", 10);
|
|
74
74
|
if (Number.isNaN(limit) || limit < 1)
|
|
75
|
-
limit =
|
|
75
|
+
limit = 30;
|
|
76
76
|
i += 1;
|
|
77
77
|
continue;
|
|
78
78
|
}
|
|
@@ -134,7 +134,7 @@ export function parseAgentSessionsArgs(args) {
|
|
|
134
134
|
throw new Error("Missing agent_id");
|
|
135
135
|
}
|
|
136
136
|
let businessDomain = "";
|
|
137
|
-
let limit;
|
|
137
|
+
let limit = 30;
|
|
138
138
|
let pretty = true;
|
|
139
139
|
for (let i = 1; i < args.length; i += 1) {
|
|
140
140
|
const arg = args[i];
|
|
@@ -150,9 +150,9 @@ export function parseAgentSessionsArgs(args) {
|
|
|
150
150
|
continue;
|
|
151
151
|
}
|
|
152
152
|
if (arg === "--limit") {
|
|
153
|
-
limit = parseInt(args[i + 1] ?? "
|
|
153
|
+
limit = parseInt(args[i + 1] ?? "30", 10);
|
|
154
154
|
if (Number.isNaN(limit) || limit < 1)
|
|
155
|
-
limit =
|
|
155
|
+
limit = 30;
|
|
156
156
|
i += 1;
|
|
157
157
|
continue;
|
|
158
158
|
}
|
|
@@ -176,7 +176,7 @@ export function parseAgentHistoryArgs(args) {
|
|
|
176
176
|
throw new Error("Missing conversation_id");
|
|
177
177
|
}
|
|
178
178
|
let businessDomain = "";
|
|
179
|
-
let limit;
|
|
179
|
+
let limit = 30;
|
|
180
180
|
let pretty = true;
|
|
181
181
|
for (let i = 1; i < args.length; i += 1) {
|
|
182
182
|
const arg = args[i];
|
|
@@ -192,9 +192,9 @@ export function parseAgentHistoryArgs(args) {
|
|
|
192
192
|
continue;
|
|
193
193
|
}
|
|
194
194
|
if (arg === "--limit") {
|
|
195
|
-
limit = parseInt(args[i + 1] ?? "
|
|
195
|
+
limit = parseInt(args[i + 1] ?? "30", 10);
|
|
196
196
|
if (Number.isNaN(limit) || limit < 1)
|
|
197
|
-
limit =
|
|
197
|
+
limit = 30;
|
|
198
198
|
i += 1;
|
|
199
199
|
continue;
|
|
200
200
|
}
|
|
@@ -309,7 +309,7 @@ List published agents from the agent-factory API.
|
|
|
309
309
|
Options:
|
|
310
310
|
--name <text> Filter by name
|
|
311
311
|
--offset <n> Pagination offset (default: 0)
|
|
312
|
-
--limit <n> Max items to return (default:
|
|
312
|
+
--limit <n> Max items to return (default: 30)
|
|
313
313
|
--category-id <id> Filter by category
|
|
314
314
|
--custom-space-id <id> Filter by custom space
|
|
315
315
|
--is-to-square <0|1> Is to square (default: 1)
|
|
@@ -326,7 +326,7 @@ Options:
|
|
|
326
326
|
List all conversations for an agent.
|
|
327
327
|
|
|
328
328
|
Options:
|
|
329
|
-
--limit <n> Max conversations to return
|
|
329
|
+
--limit <n> Max conversations to return (default: 30)
|
|
330
330
|
-bd, --biz-domain <value> Business domain (default: bd_public)
|
|
331
331
|
--pretty Pretty-print JSON output (default)`);
|
|
332
332
|
return 0;
|
|
@@ -339,7 +339,7 @@ Options:
|
|
|
339
339
|
Show message history for a conversation.
|
|
340
340
|
|
|
341
341
|
Options:
|
|
342
|
-
--limit <n> Max messages to return
|
|
342
|
+
--limit <n> Max messages to return (default: 30)
|
|
343
343
|
-bd, --biz-domain <value> Business domain (default: bd_public)
|
|
344
344
|
--pretty Pretty-print JSON output (default)`);
|
|
345
345
|
return 0;
|
|
@@ -462,7 +462,7 @@ List published agents from the agent-factory API.
|
|
|
462
462
|
Options:
|
|
463
463
|
--name <text> Filter by name
|
|
464
464
|
--offset <n> Pagination offset (default: 0)
|
|
465
|
-
--limit <n> Max items to return (default:
|
|
465
|
+
--limit <n> Max items to return (default: 30)
|
|
466
466
|
--category-id <id> Filter by category
|
|
467
467
|
--custom-space-id <id> Filter by custom space
|
|
468
468
|
--is-to-square <0|1> Is to square (default: 1)
|
|
@@ -509,7 +509,7 @@ async function runAgentSessionsCommand(args) {
|
|
|
509
509
|
List all conversations for an agent.
|
|
510
510
|
|
|
511
511
|
Options:
|
|
512
|
-
--limit <n> Max conversations to return
|
|
512
|
+
--limit <n> Max conversations to return (default: 30)
|
|
513
513
|
-bd, --biz-domain <value> Business domain (default: bd_public)
|
|
514
514
|
--pretty Pretty-print JSON output (default)`);
|
|
515
515
|
return 0;
|
|
@@ -546,7 +546,7 @@ async function runAgentHistoryCommand(args) {
|
|
|
546
546
|
Show message history for a conversation.
|
|
547
547
|
|
|
548
548
|
Options:
|
|
549
|
-
--limit <n> Max messages to return
|
|
549
|
+
--limit <n> Max messages to return (default: 30)
|
|
550
550
|
-bd, --biz-domain <value> Business domain (default: bd_public)
|
|
551
551
|
--pretty Pretty-print JSON output (default)`);
|
|
552
552
|
return 0;
|
package/dist/commands/auth.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import { clearPlatformSession, deletePlatform, getConfigDir, getCurrentPlatform, getPlatformAlias, hasPlatform, listPlatforms, loadTokenConfig, resolvePlatformIdentifier, setCurrentPlatform, setPlatformAlias, } from "../config/store.js";
|
|
2
|
-
import { formatHttpError, normalizeBaseUrl, oauth2Login, playwrightLogin, } from "../auth/oauth.js";
|
|
1
|
+
import { clearPlatformSession, deletePlatform, getConfigDir, getCurrentPlatform, getPlatformAlias, hasPlatform, listPlatforms, loadClientConfig, loadTokenConfig, resolvePlatformIdentifier, setCurrentPlatform, setPlatformAlias, } from "../config/store.js";
|
|
2
|
+
import { buildCopyCommand, formatHttpError, normalizeBaseUrl, oauth2Login, playwrightLogin, refreshTokenLogin, } from "../auth/oauth.js";
|
|
3
3
|
export async function runAuthCommand(args) {
|
|
4
4
|
const target = args[0];
|
|
5
5
|
const rest = args.slice(1);
|
|
6
6
|
if (!target || target === "--help" || target === "-h") {
|
|
7
7
|
console.log(`kweaver auth login <url> [options] Login to a platform (browser OAuth2 by default)
|
|
8
8
|
kweaver auth <url> Login (shorthand; same options as login)
|
|
9
|
+
kweaver auth export [url|alias] [--json] Export credentials; run printed command on a headless host
|
|
9
10
|
kweaver auth status [url|alias] Show current auth status
|
|
10
11
|
kweaver auth list List saved platforms
|
|
11
12
|
kweaver auth use <url|alias> Switch active platform
|
|
@@ -18,6 +19,9 @@ Login options:
|
|
|
18
19
|
Use the platform's web app client ID to get the same permissions
|
|
19
20
|
as the browser. Find it in DevTools: /oauth2/auth?client_id=<id>
|
|
20
21
|
--client-secret <s> Client secret (omit for public/PKCE clients)
|
|
22
|
+
--refresh-token <t> Use on a machine without a browser: exchange refresh token for access token.
|
|
23
|
+
Requires --client-id and --client-secret.
|
|
24
|
+
Get these from the callback page after browser login or \`auth export\`.
|
|
21
25
|
-u, --username Username (with -p triggers Playwright headless login)
|
|
22
26
|
-p, --password Password
|
|
23
27
|
--playwright Force Playwright browser login even without -u/-p
|
|
@@ -26,7 +30,7 @@ Login options:
|
|
|
26
30
|
}
|
|
27
31
|
if (target === "login") {
|
|
28
32
|
if (rest[0] === "--help" || rest[0] === "-h") {
|
|
29
|
-
console.log(`kweaver auth login <platform-url> [--alias <name>] [-u user] [-p pass] [--playwright]`);
|
|
33
|
+
console.log(`kweaver auth login <platform-url> [--alias <name>] [-u user] [-p pass] [--playwright] [--refresh-token T --client-id ID --client-secret S]`);
|
|
30
34
|
return 0;
|
|
31
35
|
}
|
|
32
36
|
const url = rest[0];
|
|
@@ -36,7 +40,11 @@ Login options:
|
|
|
36
40
|
}
|
|
37
41
|
return runAuthCommand([url, ...rest.slice(1)]);
|
|
38
42
|
}
|
|
39
|
-
if (target
|
|
43
|
+
if (target === "export") {
|
|
44
|
+
return runAuthExportCommand(rest);
|
|
45
|
+
}
|
|
46
|
+
const LOGIN_SUBCOMMANDS = new Set(["status", "list", "use", "delete", "logout", "export"]);
|
|
47
|
+
if (target && !LOGIN_SUBCOMMANDS.has(target)) {
|
|
40
48
|
try {
|
|
41
49
|
const normalizedTarget = normalizeBaseUrl(target);
|
|
42
50
|
const alias = readOption(args, "--alias");
|
|
@@ -45,9 +53,21 @@ Login options:
|
|
|
45
53
|
const usePlaywright = args.includes("--playwright");
|
|
46
54
|
const clientId = readOption(args, "--client-id");
|
|
47
55
|
const clientSecret = readOption(args, "--client-secret");
|
|
56
|
+
const refreshToken = readOption(args, "--refresh-token");
|
|
48
57
|
const tlsInsecure = args.includes("--insecure") || args.includes("-k");
|
|
49
58
|
let token;
|
|
50
|
-
if (
|
|
59
|
+
if (refreshToken) {
|
|
60
|
+
if (!clientId || !clientSecret) {
|
|
61
|
+
console.error("--refresh-token requires --client-id and --client-secret.\n");
|
|
62
|
+
console.error("Get these values from the callback page after a browser login or `kweaver auth export`.");
|
|
63
|
+
return 1;
|
|
64
|
+
}
|
|
65
|
+
console.log("Logging in with refresh token (no browser)...");
|
|
66
|
+
token = await refreshTokenLogin(normalizedTarget, {
|
|
67
|
+
clientId, clientSecret, refreshToken, tlsInsecure,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
else if (username && password) {
|
|
51
71
|
// Headless Playwright login with credentials
|
|
52
72
|
console.log("Logging in (headless)...");
|
|
53
73
|
token = await playwrightLogin(normalizedTarget, { username, password, tlsInsecure });
|
|
@@ -213,7 +233,7 @@ Login options:
|
|
|
213
233
|
return 0;
|
|
214
234
|
}
|
|
215
235
|
console.error("Usage: kweaver auth login <platform-url> [--alias <name>] [-u user] [-p pass] [--playwright]");
|
|
216
|
-
console.error(" kweaver auth
|
|
236
|
+
console.error(" kweaver auth export [platform-url|alias] [--json]");
|
|
217
237
|
console.error(" kweaver auth status [platform-url|alias]");
|
|
218
238
|
console.error(" kweaver auth list");
|
|
219
239
|
console.error(" kweaver auth use <platform-url|alias>");
|
|
@@ -221,6 +241,60 @@ Login options:
|
|
|
221
241
|
console.error(" kweaver auth delete <platform-url|alias>");
|
|
222
242
|
return 1;
|
|
223
243
|
}
|
|
244
|
+
async function runAuthExportCommand(args) {
|
|
245
|
+
if (args[0] === "--help" || args[0] === "-h") {
|
|
246
|
+
console.log(`kweaver auth export [platform-url|alias] [--json]
|
|
247
|
+
|
|
248
|
+
Export OAuth2 credentials for copying to a headless host (no browser there).
|
|
249
|
+
Prints clientId, clientSecret, refreshToken, and a command to run on that machine.
|
|
250
|
+
|
|
251
|
+
Options:
|
|
252
|
+
--json Output as JSON (machine-readable)`);
|
|
253
|
+
return 0;
|
|
254
|
+
}
|
|
255
|
+
const jsonOutput = args.includes("--json");
|
|
256
|
+
const positional = args.find((a) => !a.startsWith("-"));
|
|
257
|
+
const resolved = positional ? resolvePlatformIdentifier(positional) : null;
|
|
258
|
+
const platform = resolved && /^https?:\/\//.test(resolved) ? normalizeBaseUrl(resolved) : resolved ?? getCurrentPlatform();
|
|
259
|
+
if (!platform) {
|
|
260
|
+
console.error("No active platform. Run `kweaver auth login <platform-url>` first.");
|
|
261
|
+
return 1;
|
|
262
|
+
}
|
|
263
|
+
const client = loadClientConfig(platform);
|
|
264
|
+
const token = loadTokenConfig(platform);
|
|
265
|
+
const clientId = client?.clientId ?? "";
|
|
266
|
+
const clientSecret = client?.clientSecret ?? "";
|
|
267
|
+
const refreshToken = token?.refreshToken ?? "";
|
|
268
|
+
const tlsInsecure = token?.tlsInsecure;
|
|
269
|
+
if (!clientId || !refreshToken) {
|
|
270
|
+
console.error(`Incomplete credentials for ${platform}.\n` +
|
|
271
|
+
(!clientId ? " Missing: client registration (client.json)\n" : "") +
|
|
272
|
+
(!refreshToken ? " Missing: refresh token (token.json)\n" : "") +
|
|
273
|
+
`Run \`kweaver auth login ${platform}\` first.`);
|
|
274
|
+
return 1;
|
|
275
|
+
}
|
|
276
|
+
if (jsonOutput) {
|
|
277
|
+
console.log(JSON.stringify({
|
|
278
|
+
baseUrl: platform,
|
|
279
|
+
clientId,
|
|
280
|
+
clientSecret,
|
|
281
|
+
refreshToken,
|
|
282
|
+
...(tlsInsecure ? { tlsInsecure: true } : {}),
|
|
283
|
+
}));
|
|
284
|
+
return 0;
|
|
285
|
+
}
|
|
286
|
+
const cmd = buildCopyCommand(platform, clientId, clientSecret, refreshToken, tlsInsecure);
|
|
287
|
+
console.log(`Platform: ${platform}`);
|
|
288
|
+
console.log(`Client ID: ${clientId}`);
|
|
289
|
+
console.log(`Client Secret: ${clientSecret || "(none)"}`);
|
|
290
|
+
console.log(`Refresh Token: ${refreshToken}`);
|
|
291
|
+
console.log("");
|
|
292
|
+
console.log("On a machine without a browser, run:\n");
|
|
293
|
+
console.log(` ${cmd}`);
|
|
294
|
+
console.log("");
|
|
295
|
+
console.log("Keep these credentials secure.");
|
|
296
|
+
return 0;
|
|
297
|
+
}
|
|
224
298
|
function readOption(args, name) {
|
|
225
299
|
const index = args.findIndex((arg) => arg === name);
|
|
226
300
|
if (index === -1) {
|
package/dist/commands/bkn.d.ts
CHANGED
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
import { type BknEncodingImportOptions } from "../utils/bkn-encoding.js";
|
|
2
|
+
export interface PollOptions<T> {
|
|
3
|
+
fn: () => Promise<{
|
|
4
|
+
done: boolean;
|
|
5
|
+
value: T;
|
|
6
|
+
}>;
|
|
7
|
+
interval: number;
|
|
8
|
+
timeout: number;
|
|
9
|
+
maxInterval?: number;
|
|
10
|
+
_sleep?: (ms: number) => Promise<void>;
|
|
11
|
+
}
|
|
12
|
+
export declare function pollWithBackoff<T>(opts: PollOptions<T>): Promise<T>;
|
|
2
13
|
export interface KnListOptions {
|
|
3
14
|
offset: number;
|
|
4
15
|
limit: number;
|
package/dist/commands/bkn.js
CHANGED
|
@@ -14,6 +14,19 @@ import { downloadBkn, uploadBkn } from "../api/bkn-backend.js";
|
|
|
14
14
|
import { formatCallOutput } from "./call.js";
|
|
15
15
|
import { resolveBusinessDomain } from "../config/store.js";
|
|
16
16
|
import { runDsImportCsv } from "./ds.js";
|
|
17
|
+
export async function pollWithBackoff(opts) {
|
|
18
|
+
const { fn, timeout, maxInterval = 15000, _sleep = (ms) => new Promise(r => setTimeout(r, ms)) } = opts;
|
|
19
|
+
let currentInterval = opts.interval;
|
|
20
|
+
const deadline = Date.now() + timeout;
|
|
21
|
+
while (Date.now() < deadline) {
|
|
22
|
+
const result = await fn();
|
|
23
|
+
if (result.done)
|
|
24
|
+
return result.value;
|
|
25
|
+
await _sleep(currentInterval);
|
|
26
|
+
currentInterval = Math.min(currentInterval * 2, maxInterval);
|
|
27
|
+
}
|
|
28
|
+
throw new Error(`Polling timed out after ${timeout}ms`);
|
|
29
|
+
}
|
|
17
30
|
export function formatSimpleKnList(text, pretty, includeDetail = false) {
|
|
18
31
|
const parsed = JSON.parse(text);
|
|
19
32
|
const entries = Array.isArray(parsed.entries) ? parsed.entries : [];
|
|
@@ -27,7 +40,7 @@ export function formatSimpleKnList(text, pretty, includeDetail = false) {
|
|
|
27
40
|
}
|
|
28
41
|
export function parseKnListArgs(args) {
|
|
29
42
|
let offset = 0;
|
|
30
|
-
let limit =
|
|
43
|
+
let limit = 30;
|
|
31
44
|
let sort = "update_time";
|
|
32
45
|
let direction = "desc";
|
|
33
46
|
let businessDomain = "";
|
|
@@ -49,9 +62,9 @@ export function parseKnListArgs(args) {
|
|
|
49
62
|
continue;
|
|
50
63
|
}
|
|
51
64
|
if (arg === "--limit") {
|
|
52
|
-
limit = parseInt(args[i + 1] ?? "
|
|
65
|
+
limit = parseInt(args[i + 1] ?? "30", 10);
|
|
53
66
|
if (Number.isNaN(limit) || limit < 1)
|
|
54
|
-
limit =
|
|
67
|
+
limit = 30;
|
|
55
68
|
i += 1;
|
|
56
69
|
continue;
|
|
57
70
|
}
|
|
@@ -582,7 +595,7 @@ export function parseKnObjectTypeQueryArgs(args) {
|
|
|
582
595
|
body.search_after = searchAfter;
|
|
583
596
|
}
|
|
584
597
|
if (typeof body.limit !== "number" || !Number.isFinite(body.limit) || body.limit < 1) {
|
|
585
|
-
body.limit =
|
|
598
|
+
body.limit = 50;
|
|
586
599
|
}
|
|
587
600
|
if (!businessDomain)
|
|
588
601
|
businessDomain = resolveBusinessDomain();
|
|
@@ -1126,7 +1139,7 @@ kweaver bkn object-type properties <kn-id> <ot-id> '<json>' [--pretty] [-bd valu
|
|
|
1126
1139
|
list: List object types (schema) from ontology-manager.
|
|
1127
1140
|
get: Get single object type details.
|
|
1128
1141
|
create/update/delete: Schema CRUD (create requires dataview-id). update: merge flags (--add-property / --update-property / --remove-property, etc.) GET-merge-PUT; or full JSON as third arg.
|
|
1129
|
-
query: Query via ontology-query API. Default limit is
|
|
1142
|
+
query: Query via ontology-query API. Default limit is 50 if not specified. Use --search-after for pagination.
|
|
1130
1143
|
properties: Query instance properties by primary key.
|
|
1131
1144
|
|
|
1132
1145
|
properties JSON format: {"_instance_identities":[{"<primary-key>":"<value>"}],"properties":["prop1","prop2"]}`);
|
|
@@ -1719,26 +1732,35 @@ query/execute: Query or execute actions. execute has side effects - only use whe
|
|
|
1719
1732
|
console.log(formatCallOutput(result, options.pretty));
|
|
1720
1733
|
return 0;
|
|
1721
1734
|
}
|
|
1722
|
-
const deadline = Date.now() + options.timeout * 1000;
|
|
1723
1735
|
let lastBody = result;
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1736
|
+
try {
|
|
1737
|
+
lastBody = await pollWithBackoff({
|
|
1738
|
+
fn: async () => {
|
|
1739
|
+
const status = extractStatus(lastBody);
|
|
1740
|
+
if (TERMINAL_STATUSES.includes(status.toUpperCase())) {
|
|
1741
|
+
return { done: true, value: lastBody };
|
|
1742
|
+
}
|
|
1743
|
+
lastBody = await actionExecutionGet({
|
|
1744
|
+
baseUrl: token.baseUrl,
|
|
1745
|
+
accessToken: token.accessToken,
|
|
1746
|
+
knId: options.knId,
|
|
1747
|
+
executionId,
|
|
1748
|
+
businessDomain: options.businessDomain,
|
|
1749
|
+
});
|
|
1750
|
+
return { done: false, value: lastBody };
|
|
1751
|
+
},
|
|
1752
|
+
interval: 2000,
|
|
1753
|
+
timeout: options.timeout * 1000,
|
|
1737
1754
|
});
|
|
1738
1755
|
}
|
|
1739
|
-
|
|
1756
|
+
catch {
|
|
1757
|
+
console.error(`Action execution did not complete within ${options.timeout}s`);
|
|
1758
|
+
console.log(formatCallOutput(lastBody, options.pretty));
|
|
1759
|
+
return 1;
|
|
1760
|
+
}
|
|
1761
|
+
const finalStatus = extractStatus(lastBody);
|
|
1740
1762
|
console.log(formatCallOutput(lastBody, options.pretty));
|
|
1741
|
-
return 1;
|
|
1763
|
+
return finalStatus.toUpperCase() === "SUCCESS" ? 0 : 1;
|
|
1742
1764
|
}
|
|
1743
1765
|
catch (error) {
|
|
1744
1766
|
console.error(formatHttpError(error));
|
|
@@ -1802,7 +1824,7 @@ Options for list: --limit, --need-total, --action-type-id, --status, --trigger-t
|
|
|
1802
1824
|
}
|
|
1803
1825
|
let pretty = true;
|
|
1804
1826
|
let businessDomain = "";
|
|
1805
|
-
let limit;
|
|
1827
|
+
let limit = 30;
|
|
1806
1828
|
let needTotal;
|
|
1807
1829
|
let actionTypeId;
|
|
1808
1830
|
let status;
|
|
@@ -1955,7 +1977,7 @@ List business knowledge networks from the ontology-manager API.
|
|
|
1955
1977
|
|
|
1956
1978
|
Options:
|
|
1957
1979
|
--offset <n> Offset (default: 0)
|
|
1958
|
-
--limit <n> Limit (default:
|
|
1980
|
+
--limit <n> Limit (default: 30)
|
|
1959
1981
|
--sort <key> Sort field (default: update_time)
|
|
1960
1982
|
--direction <asc|desc> Sort direction (default: desc)
|
|
1961
1983
|
--name-pattern <s> Filter by name pattern
|
|
@@ -2274,18 +2296,24 @@ async function runKnCreateFromDsCommand(args, sampleRows) {
|
|
|
2274
2296
|
if (options.build) {
|
|
2275
2297
|
console.error("Building ...");
|
|
2276
2298
|
await buildKnowledgeNetwork({ ...base, knId });
|
|
2277
|
-
const deadline = Date.now() + options.timeout * 1000;
|
|
2278
2299
|
const TERMINAL = ["completed", "failed", "success"];
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2300
|
+
try {
|
|
2301
|
+
statusStr = await pollWithBackoff({
|
|
2302
|
+
fn: async () => {
|
|
2303
|
+
const statusBody = await getBuildStatus({ ...base, knId });
|
|
2304
|
+
const statusParsed = JSON.parse(statusBody);
|
|
2305
|
+
const jobs = Array.isArray(statusParsed) ? statusParsed : (statusParsed.entries ?? []);
|
|
2306
|
+
const state = (jobs[0]?.state ?? "running").toLowerCase();
|
|
2307
|
+
if (TERMINAL.includes(state))
|
|
2308
|
+
return { done: true, value: state };
|
|
2309
|
+
return { done: false, value: "running" };
|
|
2310
|
+
},
|
|
2311
|
+
interval: 2000,
|
|
2312
|
+
timeout: options.timeout * 1000,
|
|
2313
|
+
});
|
|
2314
|
+
}
|
|
2315
|
+
catch {
|
|
2316
|
+
// timeout — statusStr remains "skipped"
|
|
2289
2317
|
}
|
|
2290
2318
|
}
|
|
2291
2319
|
const output = {
|
|
@@ -2456,30 +2484,37 @@ async function runKnBuildCommand(args) {
|
|
|
2456
2484
|
return 0;
|
|
2457
2485
|
}
|
|
2458
2486
|
console.error("Waiting for build to complete ...");
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2487
|
+
try {
|
|
2488
|
+
const { state, detail } = await pollWithBackoff({
|
|
2489
|
+
fn: async () => {
|
|
2490
|
+
const body = await getBuildStatus({
|
|
2491
|
+
baseUrl: token.baseUrl,
|
|
2492
|
+
accessToken: token.accessToken,
|
|
2493
|
+
knId: options.knId,
|
|
2494
|
+
businessDomain: options.businessDomain,
|
|
2495
|
+
});
|
|
2496
|
+
const parsed = JSON.parse(body);
|
|
2497
|
+
const jobs = Array.isArray(parsed) ? parsed : (parsed.entries ?? parsed.data ?? []);
|
|
2498
|
+
const job = jobs[0];
|
|
2499
|
+
const st = (job?.state ?? "running").toLowerCase();
|
|
2500
|
+
const dt = job?.state_detail;
|
|
2501
|
+
if (TERMINAL_STATES.includes(st))
|
|
2502
|
+
return { done: true, value: { state: st, detail: dt } };
|
|
2503
|
+
return { done: false, value: { state: st } };
|
|
2504
|
+
},
|
|
2505
|
+
interval: 2000,
|
|
2506
|
+
timeout: options.timeout * 1000,
|
|
2467
2507
|
});
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
const state = (job?.state ?? "running").toLowerCase();
|
|
2472
|
-
const detail = job?.state_detail;
|
|
2473
|
-
if (TERMINAL_STATES.includes(state)) {
|
|
2474
|
-
console.log(state);
|
|
2475
|
-
if (detail) {
|
|
2476
|
-
console.log(`Detail: ${detail}`);
|
|
2477
|
-
}
|
|
2478
|
-
return state === "failed" ? 1 : 0;
|
|
2508
|
+
console.log(state);
|
|
2509
|
+
if (detail) {
|
|
2510
|
+
console.log(`Detail: ${detail}`);
|
|
2479
2511
|
}
|
|
2512
|
+
return state === "failed" ? 1 : 0;
|
|
2513
|
+
}
|
|
2514
|
+
catch {
|
|
2515
|
+
console.error(`Build did not complete within ${options.timeout}s`);
|
|
2516
|
+
return 1;
|
|
2480
2517
|
}
|
|
2481
|
-
console.error(`Build did not complete within ${options.timeout}s`);
|
|
2482
|
-
return 1;
|
|
2483
2518
|
}
|
|
2484
2519
|
catch (error) {
|
|
2485
2520
|
console.error(formatHttpError(error));
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createInterface } from "node:readline";
|
|
2
2
|
import { ensureValidToken, formatHttpError, with401RefreshRetry } from "../auth/oauth.js";
|
|
3
|
-
import { deleteDataView, findDataView, getDataView, listDataViews, } from "../api/dataviews.js";
|
|
3
|
+
import { deleteDataView, findDataView, getDataView, listDataViews, queryDataView, } from "../api/dataviews.js";
|
|
4
4
|
import { formatCallOutput } from "./call.js";
|
|
5
5
|
import { resolveBusinessDomain } from "../config/store.js";
|
|
6
6
|
function confirmYes(prompt) {
|
|
@@ -22,10 +22,12 @@ Subcommands:
|
|
|
22
22
|
list [--datasource-id <id>] [--type <atomic|custom>] [--limit <n>] [-bd value] [--pretty]
|
|
23
23
|
find --name <name> [--exact] [--datasource-id <id>] [--wait] [--no-wait] [--timeout <ms>] [-bd value] [--pretty]
|
|
24
24
|
get <id> [-bd value] [--pretty]
|
|
25
|
+
query <id> [--sql <sql>] [--limit <n>] [--offset <n>] [--need-total] [-bd value] [--pretty]
|
|
25
26
|
delete <id> [-y] [-bd value]
|
|
26
27
|
|
|
27
28
|
list — list all data views (no keyword search)
|
|
28
|
-
find — search by name; default fuzzy, --exact for strict match, --wait to poll
|
|
29
|
+
find — search by name; default fuzzy, --exact for strict match, --wait to poll
|
|
30
|
+
query — run SQL query against a data view (mdl-uniquery); omit --sql to use view default SQL`);
|
|
29
31
|
return 0;
|
|
30
32
|
}
|
|
31
33
|
const dispatch = () => {
|
|
@@ -35,6 +37,8 @@ Subcommands:
|
|
|
35
37
|
return runDataviewFindCommand(rest);
|
|
36
38
|
if (subcommand === "get")
|
|
37
39
|
return runDataviewGetCommand(rest);
|
|
40
|
+
if (subcommand === "query")
|
|
41
|
+
return runDataviewQueryCommand(rest);
|
|
38
42
|
if (subcommand === "delete")
|
|
39
43
|
return runDataviewDeleteCommand(rest);
|
|
40
44
|
return Promise.resolve(-1);
|
|
@@ -204,6 +208,61 @@ async function runDataviewGetCommand(args) {
|
|
|
204
208
|
console.log(formatCallOutput(JSON.stringify(view), pretty));
|
|
205
209
|
return 0;
|
|
206
210
|
}
|
|
211
|
+
async function runDataviewQueryCommand(args) {
|
|
212
|
+
const { businessDomain, pretty } = parseDataviewCommonArgs(args);
|
|
213
|
+
let sql;
|
|
214
|
+
let limit = 50;
|
|
215
|
+
let offset = 0;
|
|
216
|
+
let needTotal = false;
|
|
217
|
+
if (args.length === 0 || args[0].startsWith("-")) {
|
|
218
|
+
console.error("Usage: kweaver dataview query <id> [--sql <sql>] [--limit <n>] [--offset <n>] [--need-total] [-bd value] [--pretty]");
|
|
219
|
+
return 1;
|
|
220
|
+
}
|
|
221
|
+
const id = args[0];
|
|
222
|
+
const tail = args.slice(1);
|
|
223
|
+
for (let i = 0; i < tail.length; i += 1) {
|
|
224
|
+
const arg = tail[i];
|
|
225
|
+
if (arg === "-bd" || arg === "--biz-domain") {
|
|
226
|
+
i += 1;
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
229
|
+
if (arg === "--pretty")
|
|
230
|
+
continue;
|
|
231
|
+
if ((arg === "--sql" || arg === "-s") && tail[i + 1]) {
|
|
232
|
+
sql = tail[++i];
|
|
233
|
+
continue;
|
|
234
|
+
}
|
|
235
|
+
if (arg === "--limit" && tail[i + 1]) {
|
|
236
|
+
const n = Number.parseInt(tail[++i], 10);
|
|
237
|
+
if (!Number.isNaN(n))
|
|
238
|
+
limit = n;
|
|
239
|
+
continue;
|
|
240
|
+
}
|
|
241
|
+
if (arg === "--offset" && tail[i + 1]) {
|
|
242
|
+
const n = Number.parseInt(tail[++i], 10);
|
|
243
|
+
if (!Number.isNaN(n))
|
|
244
|
+
offset = n;
|
|
245
|
+
continue;
|
|
246
|
+
}
|
|
247
|
+
if (arg === "--need-total") {
|
|
248
|
+
needTotal = true;
|
|
249
|
+
continue;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
const token = await ensureValidToken();
|
|
253
|
+
const result = await queryDataView({
|
|
254
|
+
baseUrl: token.baseUrl,
|
|
255
|
+
accessToken: token.accessToken,
|
|
256
|
+
businessDomain,
|
|
257
|
+
id,
|
|
258
|
+
sql,
|
|
259
|
+
offset,
|
|
260
|
+
limit,
|
|
261
|
+
needTotal,
|
|
262
|
+
});
|
|
263
|
+
console.log(formatCallOutput(JSON.stringify(result), pretty));
|
|
264
|
+
return 0;
|
|
265
|
+
}
|
|
207
266
|
async function runDataviewDeleteCommand(args) {
|
|
208
267
|
let id = "";
|
|
209
268
|
let yes = false;
|