@kweaver-ai/kweaver-sdk 0.6.2 → 0.6.4
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 +7 -3
- package/README.zh.md +7 -3
- package/dist/api/dataflow.js +4 -1
- package/dist/api/skills.d.ts +6 -6
- package/dist/api/skills.js +23 -9
- package/dist/api/vega.d.ts +2 -0
- package/dist/api/vega.js +8 -13
- package/dist/auth/oauth.d.ts +69 -0
- package/dist/auth/oauth.js +647 -1
- package/dist/cli.js +1 -1
- package/dist/commands/agent-chat.js +1 -1
- package/dist/commands/agent.d.ts +9 -0
- package/dist/commands/agent.js +44 -4
- package/dist/commands/auth.js +145 -18
- package/dist/commands/bkn-schema.js +6 -1
- package/dist/commands/config.js +19 -9
- package/dist/commands/context-loader.js +8 -2
- package/dist/commands/dataflow.js +49 -7
- package/dist/commands/ds.d.ts +1 -0
- package/dist/commands/ds.js +10 -10
- package/dist/commands/skill.js +4 -4
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -0
- package/package.json +1 -2
package/dist/commands/agent.d.ts
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
/** Build llm_config with valid defaults for fields that mf-model-api validates. */
|
|
2
|
+
export declare function buildLlmConfig(id: string, name: string, maxTokens: number): Record<string, unknown>;
|
|
3
|
+
/** Resolve LLM model name from mf-model-manager API by model ID. Falls back to llmId on failure. */
|
|
4
|
+
export declare function resolveLlmName(options: {
|
|
5
|
+
baseUrl: string;
|
|
6
|
+
accessToken: string;
|
|
7
|
+
llmId: string;
|
|
8
|
+
businessDomain?: string;
|
|
9
|
+
}): Promise<string>;
|
|
1
10
|
export interface AgentListOptions {
|
|
2
11
|
name: string;
|
|
3
12
|
offset: number;
|
package/dist/commands/agent.js
CHANGED
|
@@ -7,6 +7,44 @@ import { formatCallOutput } from "./call.js";
|
|
|
7
7
|
import { resolveBusinessDomain } from "../config/store.js";
|
|
8
8
|
import { promises as fs } from "fs";
|
|
9
9
|
import { join, dirname, basename, extname } from "path";
|
|
10
|
+
import { buildHeaders } from "../api/headers.js";
|
|
11
|
+
/** Build llm_config with valid defaults for fields that mf-model-api validates. */
|
|
12
|
+
export function buildLlmConfig(id, name, maxTokens) {
|
|
13
|
+
return {
|
|
14
|
+
id,
|
|
15
|
+
name,
|
|
16
|
+
max_tokens: maxTokens,
|
|
17
|
+
temperature: 0.7,
|
|
18
|
+
top_p: 1,
|
|
19
|
+
top_k: 1,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
/** Resolve LLM model name from mf-model-manager API by model ID. Falls back to llmId on failure. */
|
|
23
|
+
export async function resolveLlmName(options) {
|
|
24
|
+
const { baseUrl, accessToken, llmId, businessDomain = "bd_public" } = options;
|
|
25
|
+
const base = baseUrl.replace(/\/+$/, "");
|
|
26
|
+
const url = `${base}/api/mf-model-manager/v1/llm/list?page=1&size=50`;
|
|
27
|
+
try {
|
|
28
|
+
const response = await fetch(url, {
|
|
29
|
+
method: "GET",
|
|
30
|
+
headers: buildHeaders(accessToken, businessDomain),
|
|
31
|
+
});
|
|
32
|
+
if (!response.ok)
|
|
33
|
+
return llmId;
|
|
34
|
+
const body = (await response.json());
|
|
35
|
+
const items = (body.data ?? body.entries ?? []);
|
|
36
|
+
const match = items.find((m) => String(m.model_id ?? m.id) === llmId);
|
|
37
|
+
if (match) {
|
|
38
|
+
const name = match.model_name ?? match.name;
|
|
39
|
+
if (typeof name === "string" && name)
|
|
40
|
+
return name;
|
|
41
|
+
}
|
|
42
|
+
return llmId;
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return llmId;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
10
48
|
/**
|
|
11
49
|
* 生成带时间戳的文件路径
|
|
12
50
|
* @param path 用户提供的路径
|
|
@@ -480,7 +518,7 @@ Subcommands:
|
|
|
480
518
|
chat <agent_id> -m "message" Send a single message (non-interactive)
|
|
481
519
|
sessions <agent_id> List all conversations for an agent
|
|
482
520
|
history <agent_id> <conversation_id> Show message history for a conversation
|
|
483
|
-
trace <conversation_id>
|
|
521
|
+
trace <agent_id> <conversation_id> Get trace data for a conversation`);
|
|
484
522
|
return Promise.resolve(0);
|
|
485
523
|
}
|
|
486
524
|
const dispatch = async () => {
|
|
@@ -1144,9 +1182,6 @@ Optional:
|
|
|
1144
1182
|
output: { default_format: "markdown" },
|
|
1145
1183
|
system_prompt: systemPrompt,
|
|
1146
1184
|
};
|
|
1147
|
-
if (llmId) {
|
|
1148
|
-
config.llms = [{ is_default: true, llm_config: { id: llmId, name: llmId, max_tokens: llmMaxTokens } }];
|
|
1149
|
-
}
|
|
1150
1185
|
}
|
|
1151
1186
|
const payload = {
|
|
1152
1187
|
name,
|
|
@@ -1161,6 +1196,11 @@ Optional:
|
|
|
1161
1196
|
payload.key = key;
|
|
1162
1197
|
try {
|
|
1163
1198
|
const token = await ensureValidToken();
|
|
1199
|
+
// Resolve LLM model name from model-factory before creating agent
|
|
1200
|
+
if (llmId && !configStr) {
|
|
1201
|
+
const llmName = await resolveLlmName({ baseUrl: token.baseUrl, accessToken: token.accessToken, llmId, businessDomain });
|
|
1202
|
+
config.llms = [{ is_default: true, llm_config: buildLlmConfig(llmId, llmName, llmMaxTokens) }];
|
|
1203
|
+
}
|
|
1164
1204
|
const body = await createAgent({
|
|
1165
1205
|
baseUrl: token.baseUrl,
|
|
1166
1206
|
accessToken: token.accessToken,
|
package/dist/commands/auth.js
CHANGED
|
@@ -1,14 +1,25 @@
|
|
|
1
1
|
import { isNoAuth } from "../config/no-auth.js";
|
|
2
2
|
import { autoSelectBusinessDomain, clearPlatformSession, deletePlatform, deleteUser, getActiveUser, getConfigDir, getCurrentPlatform, getPlatformAlias, hasPlatform, listPlatforms, listUserProfiles, loadClientConfig, loadTokenConfig, resolveBusinessDomain, resolvePlatformIdentifier, resolveUserId, saveNoAuthPlatform, setActiveUser, setCurrentPlatform, setPlatformAlias, } from "../config/store.js";
|
|
3
3
|
import { decodeJwtPayload } from "../config/jwt.js";
|
|
4
|
-
import { buildCopyCommand, formatHttpError, normalizeBaseUrl, oauth2Login, playwrightLogin, refreshTokenLogin, } from "../auth/oauth.js";
|
|
4
|
+
import { buildCopyCommand, formatHttpError, isStudiowebShellUnavailableError, normalizeBaseUrl, oauth2Login, oauth2PasswordSigninLogin, playwrightLogin, refreshTokenLogin, } from "../auth/oauth.js";
|
|
5
|
+
/** True when the `playwright` npm package can be imported (browser binaries may still need `npx playwright install`). */
|
|
6
|
+
async function isPlaywrightPackageResolvable() {
|
|
7
|
+
try {
|
|
8
|
+
const modName = "playwright";
|
|
9
|
+
await import(/* webpackIgnore: true */ modName);
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
5
16
|
export async function runAuthCommand(args) {
|
|
6
17
|
const target = args[0];
|
|
7
18
|
const rest = args.slice(1);
|
|
8
19
|
if (!target || target === "--help" || target === "-h") {
|
|
9
20
|
console.log(`kweaver auth login <url> [options] Login to a platform (browser OAuth2 by default)
|
|
10
21
|
kweaver auth <url> Login (shorthand; same options as login)
|
|
11
|
-
kweaver auth whoami [url|alias]
|
|
22
|
+
kweaver auth whoami [url|alias] [--json] Show current user identity (from id_token)
|
|
12
23
|
kweaver auth export [url|alias] [--json] Export credentials; run printed command on a headless host
|
|
13
24
|
kweaver auth status [url|alias] Show current auth status
|
|
14
25
|
kweaver auth list List all platforms and users (tree view)
|
|
@@ -30,16 +41,17 @@ Login options:
|
|
|
30
41
|
--port <n> Local callback port (default: 9010). Use when 9010 is occupied.
|
|
31
42
|
--no-browser Do not open a browser; print the auth URL and prompt for the callback URL or code (stdin).
|
|
32
43
|
Use on headless servers or when automatic browser launch fails.
|
|
33
|
-
-u, --username Username (with -p
|
|
34
|
-
-p, --password Password
|
|
35
|
-
--
|
|
44
|
+
-u, --username Username (with -p: tries HTTP /oauth2/signin first when the Studio web shell is available)
|
|
45
|
+
-p, --password Password (with -u: falls back to Playwright headless only when studioweb is unavailable and Playwright is installed)
|
|
46
|
+
--http-signin With -u/-p: HTTP POST /oauth2/signin only (no Playwright fallback). Uses the built-in RSA public key.
|
|
47
|
+
--playwright With -u/-p: force Playwright (skip HTTP sign-in). Without -u/-p: open Playwright for manual login.
|
|
36
48
|
--insecure, -k Skip TLS certificate verification (self-signed / dev HTTPS only)
|
|
37
49
|
--no-auth Save platform without OAuth (servers with no authentication). Same as detecting OAuth 404 during login.`);
|
|
38
50
|
return 0;
|
|
39
51
|
}
|
|
40
52
|
if (target === "login") {
|
|
41
53
|
if (rest[0] === "--help" || rest[0] === "-h") {
|
|
42
|
-
console.log(`kweaver auth login <platform-url> [--alias <name>] [--no-auth] [--no-browser] [-u user] [-p pass] [--playwright] [--refresh-token T --client-id ID --client-secret S]`);
|
|
54
|
+
console.log(`kweaver auth login <platform-url> [--alias <name>] [--no-auth] [--no-browser] [-u user] [-p pass] [--http-signin] [--playwright] [--refresh-token T --client-id ID --client-secret S]`);
|
|
43
55
|
return 0;
|
|
44
56
|
}
|
|
45
57
|
const url = rest[0];
|
|
@@ -69,6 +81,9 @@ Login options:
|
|
|
69
81
|
const username = readOption(args, "--username") ?? readOption(args, "-u");
|
|
70
82
|
const password = readOption(args, "--password") ?? readOption(args, "-p");
|
|
71
83
|
const usePlaywright = args.includes("--playwright");
|
|
84
|
+
const httpSignin = args.includes("--http-signin");
|
|
85
|
+
const oauthProduct = readOption(args, "--oauth-product");
|
|
86
|
+
const signinPublicKeyFile = readOption(args, "--signin-public-key-file");
|
|
72
87
|
const clientId = readOption(args, "--client-id");
|
|
73
88
|
const clientSecret = readOption(args, "--client-secret");
|
|
74
89
|
const refreshToken = readOption(args, "--refresh-token");
|
|
@@ -83,11 +98,16 @@ Login options:
|
|
|
83
98
|
const KNOWN_LOGIN_FLAGS = new Set([
|
|
84
99
|
"--alias", "--client-id", "--client-secret", "--refresh-token",
|
|
85
100
|
"--port", "--no-browser", "--username", "-u", "--password", "-p",
|
|
101
|
+
"--http-signin",
|
|
102
|
+
"--oauth-product",
|
|
103
|
+
"--signin-public-key-file",
|
|
86
104
|
"--playwright", "--insecure", "-k", "--no-auth", "--redirect-uri",
|
|
87
105
|
]);
|
|
88
106
|
const KNOWN_VALUE_FLAGS = new Set([
|
|
89
107
|
"--alias", "--client-id", "--client-secret", "--refresh-token",
|
|
90
108
|
"--port", "--username", "-u", "--password", "-p", "--redirect-uri",
|
|
109
|
+
"--oauth-product",
|
|
110
|
+
"--signin-public-key-file",
|
|
91
111
|
]);
|
|
92
112
|
for (let i = 0; i < args.length; i++) {
|
|
93
113
|
const a = args[i];
|
|
@@ -110,12 +130,24 @@ Login options:
|
|
|
110
130
|
if (noAuth && noBrowser) {
|
|
111
131
|
console.error("--no-auth does not require a browser; --no-browser is ignored.");
|
|
112
132
|
}
|
|
113
|
-
if (noAuth && (username || password || usePlaywright)) {
|
|
114
|
-
console.error("--no-auth cannot be used with Playwright login or -u/-p.");
|
|
133
|
+
if (noAuth && (username || password || usePlaywright || httpSignin)) {
|
|
134
|
+
console.error("--no-auth cannot be used with Playwright login, HTTP sign-in, or -u/-p.");
|
|
135
|
+
return 1;
|
|
136
|
+
}
|
|
137
|
+
if (noBrowser && (username || password || usePlaywright || httpSignin)) {
|
|
138
|
+
console.error("--no-browser cannot be used with Playwright login, HTTP sign-in, or -u/-p.");
|
|
115
139
|
return 1;
|
|
116
140
|
}
|
|
117
|
-
if (
|
|
118
|
-
console.error("--
|
|
141
|
+
if (httpSignin && usePlaywright) {
|
|
142
|
+
console.error("--http-signin cannot be used with --playwright.");
|
|
143
|
+
return 1;
|
|
144
|
+
}
|
|
145
|
+
if (httpSignin && refreshToken) {
|
|
146
|
+
console.error("--http-signin cannot be used with --refresh-token.");
|
|
147
|
+
return 1;
|
|
148
|
+
}
|
|
149
|
+
if (httpSignin && (!username || !password)) {
|
|
150
|
+
console.error("--http-signin requires -u/--username and -p/--password.");
|
|
119
151
|
return 1;
|
|
120
152
|
}
|
|
121
153
|
if (noBrowser && refreshToken) {
|
|
@@ -137,12 +169,67 @@ Login options:
|
|
|
137
169
|
clientId, clientSecret, refreshToken, tlsInsecure,
|
|
138
170
|
});
|
|
139
171
|
}
|
|
140
|
-
else if (username && password) {
|
|
141
|
-
console.log("Logging in (
|
|
172
|
+
else if (username && password && httpSignin) {
|
|
173
|
+
console.log("Logging in (HTTP /oauth2/signin)...");
|
|
174
|
+
token = await oauth2PasswordSigninLogin(normalizedTarget, {
|
|
175
|
+
username,
|
|
176
|
+
password,
|
|
177
|
+
tlsInsecure,
|
|
178
|
+
port: customPort,
|
|
179
|
+
clientId: clientId ?? undefined,
|
|
180
|
+
clientSecret: clientSecret ?? undefined,
|
|
181
|
+
oauthProduct: oauthProduct ?? undefined,
|
|
182
|
+
signinPublicKeyPemPath: signinPublicKeyFile ?? undefined,
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
else if (username && password && usePlaywright) {
|
|
186
|
+
console.log("Logging in (headless, Playwright)...");
|
|
142
187
|
token = await playwrightLogin(normalizedTarget, {
|
|
143
|
-
username,
|
|
188
|
+
username,
|
|
189
|
+
password,
|
|
190
|
+
tlsInsecure,
|
|
191
|
+
port: customPort,
|
|
144
192
|
});
|
|
145
193
|
}
|
|
194
|
+
else if (username && password) {
|
|
195
|
+
const signinOpts = {
|
|
196
|
+
username,
|
|
197
|
+
password,
|
|
198
|
+
tlsInsecure,
|
|
199
|
+
port: customPort,
|
|
200
|
+
clientId: clientId ?? undefined,
|
|
201
|
+
clientSecret: clientSecret ?? undefined,
|
|
202
|
+
oauthProduct: oauthProduct ?? undefined,
|
|
203
|
+
signinPublicKeyPemPath: signinPublicKeyFile ?? undefined,
|
|
204
|
+
};
|
|
205
|
+
console.log("Logging in (HTTP /oauth2/signin)...");
|
|
206
|
+
try {
|
|
207
|
+
token = await oauth2PasswordSigninLogin(normalizedTarget, signinOpts);
|
|
208
|
+
}
|
|
209
|
+
catch (err) {
|
|
210
|
+
if (!isStudiowebShellUnavailableError(err)) {
|
|
211
|
+
throw err;
|
|
212
|
+
}
|
|
213
|
+
const playwrightOk = await isPlaywrightPackageResolvable();
|
|
214
|
+
if (playwrightOk) {
|
|
215
|
+
process.stderr.write("Studio web sign-in shell is not available; falling back to Playwright headless login.\n");
|
|
216
|
+
console.log("Logging in (headless, Playwright)...");
|
|
217
|
+
token = await playwrightLogin(normalizedTarget, {
|
|
218
|
+
username,
|
|
219
|
+
password,
|
|
220
|
+
tlsInsecure,
|
|
221
|
+
port: customPort,
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
else {
|
|
225
|
+
console.error("Studio web sign-in shell is not available on this platform, and the Playwright package is not installed.");
|
|
226
|
+
console.error("Install Playwright for headless browser login: npm install playwright && npx playwright install chromium");
|
|
227
|
+
console.error("Alternatively, use OAuth without credentials:");
|
|
228
|
+
console.error(` kweaver auth login ${normalizedTarget} --no-browser`);
|
|
229
|
+
throw err;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
146
233
|
else if (usePlaywright) {
|
|
147
234
|
console.log("Opening browser for login (Playwright)...");
|
|
148
235
|
token = await playwrightLogin(normalizedTarget, {
|
|
@@ -217,8 +304,19 @@ Login options:
|
|
|
217
304
|
const statusTarget = resolvedTarget && /^https?:\/\//.test(resolvedTarget) ? normalizeBaseUrl(resolvedTarget) : resolvedTarget ?? undefined;
|
|
218
305
|
const platform = statusTarget ?? getCurrentPlatform();
|
|
219
306
|
if (!platform) {
|
|
220
|
-
|
|
221
|
-
|
|
307
|
+
const envRaw = process.env.KWEAVER_BASE_URL?.trim();
|
|
308
|
+
const envUrl = envRaw ? normalizeBaseUrl(envRaw) : undefined;
|
|
309
|
+
const envToken = process.env.KWEAVER_TOKEN?.trim();
|
|
310
|
+
if (!envUrl || !envToken) {
|
|
311
|
+
console.error("No active platform. Run `kweaver auth login <platform-url>` first.\n" +
|
|
312
|
+
" Tip: set KWEAVER_BASE_URL and KWEAVER_TOKEN to use this command without a saved login.");
|
|
313
|
+
return 1;
|
|
314
|
+
}
|
|
315
|
+
console.log(`Config directory: ${getConfigDir()}`);
|
|
316
|
+
console.log(`Platform: ${envUrl} (KWEAVER_BASE_URL)`);
|
|
317
|
+
console.log(`Token present: yes (KWEAVER_TOKEN)`);
|
|
318
|
+
console.log(`Refresh token: n/a (env)`);
|
|
319
|
+
return 0;
|
|
222
320
|
}
|
|
223
321
|
const token = loadTokenConfig(platform);
|
|
224
322
|
if (!token) {
|
|
@@ -359,7 +457,7 @@ Login options:
|
|
|
359
457
|
return 0;
|
|
360
458
|
}
|
|
361
459
|
console.error("Usage: kweaver auth login <platform-url> [--alias <name>] [-u user] [-p pass] [--playwright]");
|
|
362
|
-
console.error(" kweaver auth whoami [platform-url|alias]");
|
|
460
|
+
console.error(" kweaver auth whoami [platform-url|alias] [--json]");
|
|
363
461
|
console.error(" kweaver auth export [platform-url|alias] [--json]");
|
|
364
462
|
console.error(" kweaver auth status [platform-url|alias]");
|
|
365
463
|
console.error(" kweaver auth list");
|
|
@@ -456,8 +554,37 @@ Options:
|
|
|
456
554
|
const resolved = positional ? resolvePlatformIdentifier(positional) : null;
|
|
457
555
|
const platform = resolved && /^https?:\/\//.test(resolved) ? normalizeBaseUrl(resolved) : resolved ?? getCurrentPlatform();
|
|
458
556
|
if (!platform) {
|
|
459
|
-
|
|
460
|
-
|
|
557
|
+
const envRaw = process.env.KWEAVER_BASE_URL?.trim();
|
|
558
|
+
const envUrl = envRaw ? normalizeBaseUrl(envRaw) : undefined;
|
|
559
|
+
const envToken = process.env.KWEAVER_TOKEN?.trim();
|
|
560
|
+
if (!envUrl || !envToken) {
|
|
561
|
+
console.error("No active platform. Run `kweaver auth login <platform-url>` first.");
|
|
562
|
+
return 1;
|
|
563
|
+
}
|
|
564
|
+
const accessToken = envToken.replace(/^Bearer\s+/i, "");
|
|
565
|
+
const payload = decodeJwtPayload(accessToken);
|
|
566
|
+
if (jsonOutput) {
|
|
567
|
+
console.log(JSON.stringify({ platform: envUrl, source: "env", ...(payload ?? {}) }, null, 2));
|
|
568
|
+
return 0;
|
|
569
|
+
}
|
|
570
|
+
console.log(`Platform: ${envUrl}`);
|
|
571
|
+
console.log(`Source: env (KWEAVER_TOKEN)`);
|
|
572
|
+
if (payload) {
|
|
573
|
+
const uname = payload.preferred_username ?? payload.name;
|
|
574
|
+
if (uname)
|
|
575
|
+
console.log(`Username: ${uname}`);
|
|
576
|
+
console.log(`User ID: ${payload.sub ?? "(unknown)"}`);
|
|
577
|
+
console.log(`Issuer: ${payload.iss ?? "(unknown)"}`);
|
|
578
|
+
if (payload.iat)
|
|
579
|
+
console.log(`Issued: ${new Date(payload.iat * 1000).toISOString()}`);
|
|
580
|
+
if (payload.exp)
|
|
581
|
+
console.log(`Expires: ${new Date(payload.exp * 1000).toISOString()}`);
|
|
582
|
+
}
|
|
583
|
+
else {
|
|
584
|
+
console.log(`User info unavailable: opaque access token.`);
|
|
585
|
+
console.log(`Hint: run \`kweaver auth login ${envUrl}\` to obtain a full session.`);
|
|
586
|
+
}
|
|
587
|
+
return 0;
|
|
461
588
|
}
|
|
462
589
|
const token = loadTokenConfig(platform);
|
|
463
590
|
if (!token) {
|
|
@@ -1185,8 +1185,13 @@ query/execute: Query or execute actions. execute has side effects - only use whe
|
|
|
1185
1185
|
console.error("Usage: kweaver bkn action-type create <kn-id> '<json>'");
|
|
1186
1186
|
return 1;
|
|
1187
1187
|
}
|
|
1188
|
+
// Wrap in {"entries": [...]} if needed (ontology-manager expects this envelope)
|
|
1189
|
+
const entry = JSON.parse(bodyJson);
|
|
1190
|
+
const wrapped = entry && typeof entry === "object" && "entries" in entry
|
|
1191
|
+
? bodyJson
|
|
1192
|
+
: JSON.stringify({ entries: Array.isArray(entry) ? entry : [entry] });
|
|
1188
1193
|
const token = await ensureValidToken();
|
|
1189
|
-
const result = await createActionTypes({ baseUrl: token.baseUrl, accessToken: token.accessToken, knId, body:
|
|
1194
|
+
const result = await createActionTypes({ baseUrl: token.baseUrl, accessToken: token.accessToken, knId, body: wrapped, businessDomain: parsed.businessDomain });
|
|
1190
1195
|
console.log(formatCallOutput(result, parsed.pretty));
|
|
1191
1196
|
return 0;
|
|
1192
1197
|
}
|
package/dist/commands/config.js
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
import { listBusinessDomains } from "../api/business-domains.js";
|
|
2
|
-
import { withTokenRetry } from "../auth/oauth.js";
|
|
2
|
+
import { normalizeBaseUrl, withTokenRetry } from "../auth/oauth.js";
|
|
3
|
+
// Resolve platform URL: saved current platform > KWEAVER_BASE_URL (normalized to
|
|
4
|
+
// match what `auth login` writes, so env users share the same platforms/<key>/ dir).
|
|
5
|
+
function resolvePlatformUrl() {
|
|
6
|
+
const saved = getCurrentPlatform();
|
|
7
|
+
if (saved)
|
|
8
|
+
return saved;
|
|
9
|
+
const env = process.env.KWEAVER_BASE_URL?.trim();
|
|
10
|
+
return env ? normalizeBaseUrl(env) : undefined;
|
|
11
|
+
}
|
|
3
12
|
import { getCurrentPlatform, loadPlatformBusinessDomain, resolveBusinessDomain, savePlatformBusinessDomain, } from "../config/store.js";
|
|
4
13
|
const HELP = `kweaver config
|
|
5
14
|
|
|
@@ -20,9 +29,9 @@ export async function runConfigCommand(args) {
|
|
|
20
29
|
return 0;
|
|
21
30
|
}
|
|
22
31
|
if (sub === "show") {
|
|
23
|
-
const platform =
|
|
32
|
+
const platform = resolvePlatformUrl();
|
|
24
33
|
if (!platform) {
|
|
25
|
-
console.error("No active platform. Run `kweaver auth login <url>` first.");
|
|
34
|
+
console.error("No active platform. Run `kweaver auth login <url>` first.\n Tip: set KWEAVER_BASE_URL to use this command without a saved login.");
|
|
26
35
|
return 1;
|
|
27
36
|
}
|
|
28
37
|
const bd = resolveBusinessDomain(platform);
|
|
@@ -31,7 +40,8 @@ export async function runConfigCommand(args) {
|
|
|
31
40
|
: loadPlatformBusinessDomain(platform)
|
|
32
41
|
? "config"
|
|
33
42
|
: "default";
|
|
34
|
-
|
|
43
|
+
const platformSource = getCurrentPlatform() ? "" : " (KWEAVER_BASE_URL)";
|
|
44
|
+
console.log(`Platform: ${platform}${platformSource}`);
|
|
35
45
|
console.log(`Business Domain: ${bd} (${source})`);
|
|
36
46
|
return 0;
|
|
37
47
|
}
|
|
@@ -41,19 +51,19 @@ export async function runConfigCommand(args) {
|
|
|
41
51
|
console.error("Usage: kweaver config set-bd <value>");
|
|
42
52
|
return 1;
|
|
43
53
|
}
|
|
44
|
-
const platform =
|
|
54
|
+
const platform = resolvePlatformUrl();
|
|
45
55
|
if (!platform) {
|
|
46
|
-
console.error("No active platform. Run `kweaver auth login <url>` first.");
|
|
56
|
+
console.error("No active platform. Run `kweaver auth login <url>` first.\n Tip: set KWEAVER_BASE_URL to write the business domain for that platform.");
|
|
47
57
|
return 1;
|
|
48
58
|
}
|
|
49
59
|
savePlatformBusinessDomain(platform, value);
|
|
50
|
-
console.log(`Business domain set to: ${value}`);
|
|
60
|
+
console.log(`Business domain set to: ${value} (${getCurrentPlatform() ? platform : `${platform} via KWEAVER_BASE_URL`})`);
|
|
51
61
|
return 0;
|
|
52
62
|
}
|
|
53
63
|
if (sub === "list-bd") {
|
|
54
|
-
const platform =
|
|
64
|
+
const platform = resolvePlatformUrl();
|
|
55
65
|
if (!platform) {
|
|
56
|
-
console.error("No active platform. Run `kweaver auth login <url>` first.");
|
|
66
|
+
console.error("No active platform. Run `kweaver auth login <url>` first.\n Tip: set KWEAVER_BASE_URL and KWEAVER_TOKEN to use this command without a saved login.");
|
|
57
67
|
return 1;
|
|
58
68
|
}
|
|
59
69
|
try {
|
|
@@ -281,20 +281,26 @@ async function runGetPrompt(options, args, pretty) {
|
|
|
281
281
|
async function runKnSearch(options, args, pretty) {
|
|
282
282
|
let query;
|
|
283
283
|
let onlySchema = false;
|
|
284
|
+
let knIdOverride;
|
|
284
285
|
for (let i = 0; i < args.length; i += 1) {
|
|
285
286
|
const arg = args[i];
|
|
286
287
|
if (arg === "--only-schema") {
|
|
287
288
|
onlySchema = true;
|
|
288
289
|
}
|
|
290
|
+
else if ((arg === "--kn-id" || arg === "-k") && args[i + 1]) {
|
|
291
|
+
knIdOverride = args[i + 1];
|
|
292
|
+
i += 1;
|
|
293
|
+
}
|
|
289
294
|
else if (!arg.startsWith("-") && !query) {
|
|
290
295
|
query = arg;
|
|
291
296
|
}
|
|
292
297
|
}
|
|
293
298
|
if (!query) {
|
|
294
|
-
console.error("Usage: kweaver context-loader kn-search <query> [--only-schema]");
|
|
299
|
+
console.error("Usage: kweaver context-loader kn-search <query> [--kn-id <id>] [--only-schema]");
|
|
295
300
|
return 1;
|
|
296
301
|
}
|
|
297
|
-
const
|
|
302
|
+
const effectiveOptions = knIdOverride ? { ...options, knId: knIdOverride } : options;
|
|
303
|
+
const result = await knSearch(effectiveOptions, { query, only_schema: onlySchema });
|
|
298
304
|
console.log(formatOutput(result, pretty));
|
|
299
305
|
return 0;
|
|
300
306
|
}
|
|
@@ -6,6 +6,7 @@ import yargs from "yargs";
|
|
|
6
6
|
import { ensureValidToken, formatHttpError, with401RefreshRetry } from "../auth/oauth.js";
|
|
7
7
|
import { resolveBusinessDomain } from "../config/store.js";
|
|
8
8
|
import { getDataflowLogsPage, listDataflowRuns, listDataflows, runDataflowWithFile, runDataflowWithRemoteUrl, } from "../api/dataflow2.js";
|
|
9
|
+
import { createDataflow } from "../api/dataflow.js";
|
|
9
10
|
function renderTable(rows) {
|
|
10
11
|
if (rows.length === 0)
|
|
11
12
|
return "";
|
|
@@ -101,16 +102,47 @@ export async function runDataflowCommand(args) {
|
|
|
101
102
|
.fail((message, error) => {
|
|
102
103
|
throw error ?? new Error(message);
|
|
103
104
|
})
|
|
104
|
-
.command("
|
|
105
|
+
.command("create <json>", "Create a new dataflow (DAG) from a JSON definition", (command) => command
|
|
106
|
+
.positional("json", {
|
|
107
|
+
type: "string",
|
|
108
|
+
describe: "JSON body string or @file-path to read from file",
|
|
109
|
+
})
|
|
110
|
+
.option("biz-domain", { alias: "bd", type: "string" }), async (argv) => {
|
|
111
|
+
exitCode = await with401RefreshRetry(async () => {
|
|
112
|
+
const base = await requireTokenAndBusinessDomain(argv.bizDomain);
|
|
113
|
+
let raw = argv.json;
|
|
114
|
+
if (raw.startsWith("@")) {
|
|
115
|
+
const filePath = raw.slice(1);
|
|
116
|
+
await access(filePath, constants.R_OK);
|
|
117
|
+
raw = (await readFile(filePath, "utf8")).toString();
|
|
118
|
+
}
|
|
119
|
+
const body = JSON.parse(raw);
|
|
120
|
+
const dagId = await createDataflow({ ...base, body });
|
|
121
|
+
console.log(JSON.stringify({ id: dagId }, null, 2));
|
|
122
|
+
return 0;
|
|
123
|
+
});
|
|
124
|
+
})
|
|
125
|
+
.command("list", "List all dataflows", (command) => command
|
|
126
|
+
.option("biz-domain", {
|
|
105
127
|
alias: "bd",
|
|
106
128
|
type: "string",
|
|
129
|
+
})
|
|
130
|
+
.option("table", {
|
|
131
|
+
type: "boolean",
|
|
132
|
+
default: false,
|
|
133
|
+
describe: "Output as human-readable table instead of JSON",
|
|
107
134
|
}), async (argv) => {
|
|
108
135
|
exitCode = await with401RefreshRetry(async () => {
|
|
109
136
|
const base = await requireTokenAndBusinessDomain(argv.bizDomain);
|
|
110
137
|
const body = await listDataflows(base);
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
138
|
+
if (argv.table) {
|
|
139
|
+
const table = renderTable(buildListTableRows(body.dags));
|
|
140
|
+
if (table) {
|
|
141
|
+
console.log(table);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
console.log(JSON.stringify(body, null, 2));
|
|
114
146
|
}
|
|
115
147
|
return 0;
|
|
116
148
|
});
|
|
@@ -160,6 +192,11 @@ export async function runDataflowCommand(args) {
|
|
|
160
192
|
.command("runs <dagId>", "List run records for one dataflow", (command) => command
|
|
161
193
|
.positional("dagId", { type: "string" })
|
|
162
194
|
.option("since", { type: "string" })
|
|
195
|
+
.option("table", {
|
|
196
|
+
type: "boolean",
|
|
197
|
+
default: false,
|
|
198
|
+
describe: "Output as human-readable table instead of JSON",
|
|
199
|
+
})
|
|
163
200
|
.option("biz-domain", { alias: "bd", type: "string" }), async (argv) => {
|
|
164
201
|
exitCode = await with401RefreshRetry(async () => {
|
|
165
202
|
const base = await requireTokenAndBusinessDomain(argv.bizDomain);
|
|
@@ -203,9 +240,14 @@ export async function runDataflowCommand(args) {
|
|
|
203
240
|
results = results.concat(next.results);
|
|
204
241
|
}
|
|
205
242
|
}
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
243
|
+
if (argv.table) {
|
|
244
|
+
const table = renderTable(buildRunTableRows(results));
|
|
245
|
+
if (table) {
|
|
246
|
+
console.log(table);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
else {
|
|
250
|
+
console.log(JSON.stringify(results, null, 2));
|
|
209
251
|
}
|
|
210
252
|
return 0;
|
|
211
253
|
});
|
package/dist/commands/ds.d.ts
CHANGED
|
@@ -17,6 +17,7 @@ export declare function resolveFiles(pattern: string): Promise<string[]>;
|
|
|
17
17
|
export interface ImportCsvResult {
|
|
18
18
|
code: number;
|
|
19
19
|
tables: string[];
|
|
20
|
+
failed: string[];
|
|
20
21
|
tableColumns: Record<string, string[]>;
|
|
21
22
|
sampleRows: Record<string, Array<Record<string, string | null>>>;
|
|
22
23
|
}
|
package/dist/commands/ds.js
CHANGED
|
@@ -384,17 +384,17 @@ export async function runDsImportCsv(args) {
|
|
|
384
384
|
catch (error) {
|
|
385
385
|
if (error instanceof Error && error.message === "help") {
|
|
386
386
|
console.log(IMPORT_CSV_HELP);
|
|
387
|
-
return { code: 0, tables: [], tableColumns: {}, sampleRows: {} };
|
|
387
|
+
return { code: 0, tables: [], failed: [], tableColumns: {}, sampleRows: {} };
|
|
388
388
|
}
|
|
389
389
|
throw error;
|
|
390
390
|
}
|
|
391
391
|
if (!options.datasourceId) {
|
|
392
392
|
console.error("Usage: kweaver ds import-csv <ds-id> --files <glob_or_list> [options]");
|
|
393
|
-
return { code: 1, tables: [], tableColumns: {}, sampleRows: {} };
|
|
393
|
+
return { code: 1, tables: [], failed: [], tableColumns: {}, sampleRows: {} };
|
|
394
394
|
}
|
|
395
395
|
if (!options.files) {
|
|
396
396
|
console.error("Error: --files is required");
|
|
397
|
-
return { code: 1, tables: [], tableColumns: {}, sampleRows: {} };
|
|
397
|
+
return { code: 1, tables: [], failed: [], tableColumns: {}, sampleRows: {} };
|
|
398
398
|
}
|
|
399
399
|
// 1. Get credentials
|
|
400
400
|
const token = await ensureValidToken();
|
|
@@ -429,7 +429,7 @@ export async function runDsImportCsv(args) {
|
|
|
429
429
|
}
|
|
430
430
|
if (parsed.length === 0) {
|
|
431
431
|
console.error("All files were skipped — nothing to import");
|
|
432
|
-
return { code: 1, tables: [], tableColumns: {}, sampleRows: {} };
|
|
432
|
+
return { code: 1, tables: [], failed: [], tableColumns: {}, sampleRows: {} };
|
|
433
433
|
}
|
|
434
434
|
// Phase 2: Import each file in batches
|
|
435
435
|
const succeeded = [];
|
|
@@ -487,14 +487,14 @@ export async function runDsImportCsv(args) {
|
|
|
487
487
|
if (failed.length > 0) {
|
|
488
488
|
console.error(`Failed tables: ${failed.join(", ")}`);
|
|
489
489
|
}
|
|
490
|
-
|
|
491
|
-
tables: succeeded,
|
|
492
|
-
failed,
|
|
493
|
-
summary: { succeeded: succeeded.length, failed: failed.length },
|
|
494
|
-
}, null, 2));
|
|
495
|
-
return { code: failed.length > 0 ? 1 : 0, tables: succeeded, tableColumns, sampleRows };
|
|
490
|
+
return { code: failed.length > 0 ? 1 : 0, tables: succeeded, failed, tableColumns, sampleRows };
|
|
496
491
|
}
|
|
497
492
|
export async function runDsImportCsvCommand(args) {
|
|
498
493
|
const result = await runDsImportCsv(args);
|
|
494
|
+
console.log(JSON.stringify({
|
|
495
|
+
tables: result.tables,
|
|
496
|
+
failed: result.failed,
|
|
497
|
+
summary: { succeeded: result.tables.length, failed: result.failed.length },
|
|
498
|
+
}, null, 2));
|
|
499
499
|
return result.code;
|
|
500
500
|
}
|
package/dist/commands/skill.js
CHANGED
|
@@ -23,8 +23,8 @@ function printSkillHelp(subcommand) {
|
|
|
23
23
|
[--source src] [--extend-info json] [-bd value] [--pretty|--compact]`);
|
|
24
24
|
return;
|
|
25
25
|
}
|
|
26
|
-
if (subcommand === "status") {
|
|
27
|
-
console.log("kweaver skill status <skill-id> <unpublish|published|offline> [-bd value] [--pretty|--compact]");
|
|
26
|
+
if (subcommand === "set-status" || subcommand === "status") {
|
|
27
|
+
console.log("kweaver skill set-status <skill-id> <unpublish|published|offline> [-bd value] [--pretty|--compact]");
|
|
28
28
|
return;
|
|
29
29
|
}
|
|
30
30
|
if (subcommand === "delete") {
|
|
@@ -54,7 +54,7 @@ Subcommands:
|
|
|
54
54
|
market [--name kw] [--source src] [--page N] [--page-size N] [-bd value]
|
|
55
55
|
get <skill-id> [-bd value]
|
|
56
56
|
register --content-file <path> | --zip-file <path> [--source src] [--extend-info json]
|
|
57
|
-
status <skill-id> <unpublish|published|offline> [-bd value]
|
|
57
|
+
set-status <skill-id> <unpublish|published|offline> [-bd value]
|
|
58
58
|
delete <skill-id> [-y] [-bd value]
|
|
59
59
|
content <skill-id> [--raw] [--output file] [-bd value]
|
|
60
60
|
read-file <skill-id> <rel-path> [--raw] [--output file] [-bd value]
|
|
@@ -419,7 +419,7 @@ export async function runSkillCommand(args) {
|
|
|
419
419
|
return 0;
|
|
420
420
|
}
|
|
421
421
|
}
|
|
422
|
-
if (subcommand === "status") {
|
|
422
|
+
if (subcommand === "set-status" || subcommand === "status") {
|
|
423
423
|
const opts = parseStatusArgs(rest);
|
|
424
424
|
const result = await updateSkillStatus({ ...token, ...opts });
|
|
425
425
|
console.log(format(result, opts.pretty));
|
package/dist/index.d.ts
CHANGED
|
@@ -62,3 +62,4 @@ export type { TokenConfig, ContextLoaderEntry, ContextLoaderConfig, } from "./co
|
|
|
62
62
|
export type { UserProfile } from "./config/store.js";
|
|
63
63
|
export { NO_AUTH_TOKEN, isNoAuth, saveNoAuthPlatform, autoSelectBusinessDomain, getConfigDir, getCurrentPlatform, getActiveUser, setActiveUser, listUsers, listUserProfiles, resolveUserId, extractUserId, } from "./config/store.js";
|
|
64
64
|
export { decodeJwtPayload, extractUserIdFromJwt } from "./config/jwt.js";
|
|
65
|
+
export { DEFAULT_SIGNIN_RSA_MODULUS_HEX, oauth2PasswordSigninLogin, parseSigninPageHtmlProps, rsaModulusHexToSpkiPem, STUDIOWEB_LOGIN_PUBLIC_KEY_PEM, } from "./auth/oauth.js";
|
package/dist/index.js
CHANGED
|
@@ -49,3 +49,5 @@ export { HttpError, NetworkRequestError, fetchTextOrThrow } from "./utils/http.j
|
|
|
49
49
|
export { NO_AUTH_TOKEN, isNoAuth, saveNoAuthPlatform, autoSelectBusinessDomain, getConfigDir, getCurrentPlatform, getActiveUser, setActiveUser, listUsers, listUserProfiles, resolveUserId, extractUserId, } from "./config/store.js";
|
|
50
50
|
// ── JWT utilities ─────────────────────────────────────────────────────────────
|
|
51
51
|
export { decodeJwtPayload, extractUserIdFromJwt } from "./config/jwt.js";
|
|
52
|
+
// ── OAuth (advanced — CLI uses these internally; optional for custom login tools) ─
|
|
53
|
+
export { DEFAULT_SIGNIN_RSA_MODULUS_HEX, oauth2PasswordSigninLogin, parseSigninPageHtmlProps, rsaModulusHexToSpkiPem, STUDIOWEB_LOGIN_PUBLIC_KEY_PEM, } from "./auth/oauth.js";
|