@kweaver-ai/kweaver-sdk 0.5.1 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -2
- package/README.zh.md +24 -1
- package/dist/api/agent-chat.d.ts +8 -2
- package/dist/api/agent-chat.js +150 -44
- package/dist/api/agent-list.d.ts +35 -0
- package/dist/api/agent-list.js +95 -21
- package/dist/api/bkn-backend.d.ts +60 -0
- package/dist/api/bkn-backend.js +103 -10
- package/dist/api/business-domains.js +9 -5
- package/dist/api/context-loader.js +4 -1
- package/dist/api/conversations.d.ts +6 -3
- package/dist/api/conversations.js +29 -35
- package/dist/api/dataflow.js +1 -10
- package/dist/api/dataflow2.d.ts +95 -0
- package/dist/api/dataflow2.js +80 -0
- package/dist/api/datasources.js +1 -10
- package/dist/api/dataviews.js +1 -10
- package/dist/api/headers.d.ts +11 -0
- package/dist/api/headers.js +30 -0
- package/dist/api/knowledge-networks.d.ts +41 -0
- package/dist/api/knowledge-networks.js +69 -22
- package/dist/api/ontology-query.d.ts +14 -1
- package/dist/api/ontology-query.js +63 -49
- package/dist/api/semantic-search.js +2 -12
- package/dist/api/skills.d.ts +141 -0
- package/dist/api/skills.js +208 -0
- package/dist/api/vega.d.ts +54 -7
- package/dist/api/vega.js +112 -25
- package/dist/auth/oauth.d.ts +5 -1
- package/dist/auth/oauth.js +351 -95
- package/dist/cli.js +49 -5
- package/dist/client.d.ts +12 -0
- package/dist/client.js +52 -8
- package/dist/commands/agent.d.ts +33 -1
- package/dist/commands/agent.js +721 -49
- package/dist/commands/auth.js +226 -55
- package/dist/commands/bkn-ops.d.ts +77 -0
- package/dist/commands/bkn-ops.js +1056 -0
- package/dist/commands/bkn-query.d.ts +14 -0
- package/dist/commands/bkn-query.js +370 -0
- package/dist/commands/bkn-schema.d.ts +135 -0
- package/dist/commands/bkn-schema.js +1483 -0
- package/dist/commands/bkn-utils.d.ts +36 -0
- package/dist/commands/bkn-utils.js +102 -0
- package/dist/commands/bkn.d.ts +7 -113
- package/dist/commands/bkn.js +175 -2429
- package/dist/commands/call.js +8 -5
- package/dist/commands/dataflow.d.ts +1 -0
- package/dist/commands/dataflow.js +251 -0
- package/dist/commands/dataview.d.ts +7 -0
- package/dist/commands/dataview.js +38 -2
- package/dist/commands/ds.d.ts +1 -0
- package/dist/commands/ds.js +8 -1
- package/dist/commands/explore-bkn.d.ts +79 -0
- package/dist/commands/explore-bkn.js +273 -0
- package/dist/commands/explore-chat.d.ts +3 -0
- package/dist/commands/explore-chat.js +193 -0
- package/dist/commands/explore-vega.d.ts +3 -0
- package/dist/commands/explore-vega.js +71 -0
- package/dist/commands/explore.d.ts +9 -0
- package/dist/commands/explore.js +258 -0
- package/dist/commands/import-csv.d.ts +2 -0
- package/dist/commands/import-csv.js +3 -2
- package/dist/commands/skill.d.ts +26 -0
- package/dist/commands/skill.js +524 -0
- package/dist/commands/vega.js +372 -117
- package/dist/config/jwt.d.ts +6 -0
- package/dist/config/jwt.js +21 -0
- package/dist/config/no-auth.d.ts +3 -0
- package/dist/config/no-auth.js +5 -0
- package/dist/config/store.d.ts +45 -5
- package/dist/config/store.js +385 -30
- package/dist/index.d.ts +6 -1
- package/dist/index.js +5 -1
- package/dist/kweaver.d.ts +5 -0
- package/dist/kweaver.js +32 -2
- package/dist/resources/bkn.d.ts +4 -0
- package/dist/resources/bkn.js +6 -3
- package/dist/resources/conversations.d.ts +5 -2
- package/dist/resources/conversations.js +17 -3
- package/dist/resources/knowledge-networks.js +3 -8
- package/dist/resources/skills.d.ts +47 -0
- package/dist/resources/skills.js +47 -0
- package/dist/resources/vega.d.ts +11 -6
- package/dist/resources/vega.js +37 -10
- package/dist/templates/explorer/app.js +136 -0
- package/dist/templates/explorer/bkn.js +747 -0
- package/dist/templates/explorer/chat.js +980 -0
- package/dist/templates/explorer/dashboard.js +82 -0
- package/dist/templates/explorer/index.html +35 -0
- package/dist/templates/explorer/style.css +2440 -0
- package/dist/templates/explorer/vega.js +291 -0
- package/dist/utils/http.d.ts +3 -0
- package/dist/utils/http.js +37 -1
- package/package.json +9 -5
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
import { createServer } from "node:http";
|
|
2
|
+
import { readFileSync, existsSync } from "node:fs";
|
|
3
|
+
import { join, extname } from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { execSync } from "node:child_process";
|
|
6
|
+
import { ensureValidToken } from "../auth/oauth.js";
|
|
7
|
+
import { resolveBusinessDomain } from "../config/store.js";
|
|
8
|
+
import { registerBknRoutes, loadExploreMetaWithRetry, readBody } from "./explore-bkn.js";
|
|
9
|
+
import { registerChatRoutes } from "./explore-chat.js";
|
|
10
|
+
import { registerVegaRoutes } from "./explore-vega.js";
|
|
11
|
+
import { listKnowledgeNetworks } from "../api/knowledge-networks.js";
|
|
12
|
+
import { listAgents } from "../api/agent-list.js";
|
|
13
|
+
import { listVegaCatalogs } from "../api/vega.js";
|
|
14
|
+
export function parseExploreArgs(args) {
|
|
15
|
+
const opts = {
|
|
16
|
+
knId: "",
|
|
17
|
+
agentId: "",
|
|
18
|
+
port: 3721,
|
|
19
|
+
open: true,
|
|
20
|
+
businessDomain: "",
|
|
21
|
+
};
|
|
22
|
+
for (let i = 0; i < args.length; i++) {
|
|
23
|
+
const a = args[i];
|
|
24
|
+
if (a === "--help" || a === "-h")
|
|
25
|
+
throw new Error("help");
|
|
26
|
+
if (a === "--port" && args[i + 1]) {
|
|
27
|
+
opts.port = Number(args[++i]);
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
if (a === "--no-open") {
|
|
31
|
+
opts.open = false;
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
if (a === "--kn" && args[i + 1]) {
|
|
35
|
+
opts.knId = args[++i];
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
if (a === "--agent" && args[i + 1]) {
|
|
39
|
+
opts.agentId = args[++i];
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
if ((a === "-bd" || a === "--biz-domain") && args[i + 1]) {
|
|
43
|
+
opts.businessDomain = args[++i];
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return opts;
|
|
48
|
+
}
|
|
49
|
+
function printExploreHelp() {
|
|
50
|
+
console.log(`kweaver explore
|
|
51
|
+
|
|
52
|
+
Launch an interactive web UI for exploring KWeaver resources.
|
|
53
|
+
|
|
54
|
+
Usage:
|
|
55
|
+
kweaver explore [options]
|
|
56
|
+
|
|
57
|
+
Options:
|
|
58
|
+
--kn <id> Open directly to BKN tab with specified KN
|
|
59
|
+
--agent <id> Open directly to Chat tab with specified Agent
|
|
60
|
+
--port <n> HTTP server port (default: 3721)
|
|
61
|
+
--no-open Don't auto-open browser
|
|
62
|
+
-bd <value> Business domain override
|
|
63
|
+
-h, --help Show this help
|
|
64
|
+
`);
|
|
65
|
+
}
|
|
66
|
+
// MIME map for static files
|
|
67
|
+
const MIME = {
|
|
68
|
+
".html": "text/html; charset=utf-8",
|
|
69
|
+
".css": "text/css; charset=utf-8",
|
|
70
|
+
".js": "application/javascript; charset=utf-8",
|
|
71
|
+
".json": "application/json; charset=utf-8",
|
|
72
|
+
".png": "image/png",
|
|
73
|
+
".svg": "image/svg+xml",
|
|
74
|
+
};
|
|
75
|
+
/**
|
|
76
|
+
* Returns a fresh token, re-reading from disk each time.
|
|
77
|
+
* This ensures long-running server processes always use the latest
|
|
78
|
+
* access token after a refresh, rather than a stale snapshot.
|
|
79
|
+
*/
|
|
80
|
+
async function freshToken() {
|
|
81
|
+
return ensureValidToken();
|
|
82
|
+
}
|
|
83
|
+
async function startServer(opts, token, businessDomain) {
|
|
84
|
+
// 1. Load BKN meta if --kn provided
|
|
85
|
+
let bknMeta = null;
|
|
86
|
+
if (opts.knId) {
|
|
87
|
+
console.error(`Loading schema for KN ${opts.knId}...`);
|
|
88
|
+
bknMeta = await loadExploreMetaWithRetry(token, opts.knId, businessDomain);
|
|
89
|
+
console.error(`Loaded: ${bknMeta.objectTypes.length} OTs, ${bknMeta.relationTypes.length} RTs`);
|
|
90
|
+
}
|
|
91
|
+
// 2. Collect route handlers
|
|
92
|
+
const routes = new Map();
|
|
93
|
+
// Dashboard route: aggregate KN, Agents, Vega Catalogs in parallel
|
|
94
|
+
routes.set("GET /api/dashboard", async (_req, res) => {
|
|
95
|
+
try {
|
|
96
|
+
const t = await freshToken();
|
|
97
|
+
const bd = businessDomain;
|
|
98
|
+
const [knRaw, agentsRaw, catalogsRaw] = await Promise.allSettled([
|
|
99
|
+
listKnowledgeNetworks({ baseUrl: t.baseUrl, accessToken: t.accessToken, businessDomain: bd }),
|
|
100
|
+
listAgents({ baseUrl: t.baseUrl, accessToken: t.accessToken, businessDomain: bd }),
|
|
101
|
+
listVegaCatalogs({ baseUrl: t.baseUrl, accessToken: t.accessToken, businessDomain: bd }),
|
|
102
|
+
]);
|
|
103
|
+
const parseSettled = (r) => r.status === "fulfilled" ? JSON.parse(r.value) : { error: String(r.reason) };
|
|
104
|
+
const payload = {
|
|
105
|
+
kn: parseSettled(knRaw),
|
|
106
|
+
agents: parseSettled(agentsRaw),
|
|
107
|
+
catalogs: parseSettled(catalogsRaw),
|
|
108
|
+
};
|
|
109
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
110
|
+
res.end(JSON.stringify(payload));
|
|
111
|
+
}
|
|
112
|
+
catch (err) {
|
|
113
|
+
res.writeHead(500, { "Content-Type": "application/json" });
|
|
114
|
+
res.end(JSON.stringify({ error: String(err) }));
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
// BKN routes
|
|
118
|
+
if (bknMeta) {
|
|
119
|
+
const bknRoutes = registerBknRoutes(bknMeta, freshToken, businessDomain);
|
|
120
|
+
for (const [key, handler] of bknRoutes)
|
|
121
|
+
routes.set(key, handler);
|
|
122
|
+
}
|
|
123
|
+
// Dynamic KN loading: POST /api/bkn/load { knId }
|
|
124
|
+
routes.set("POST /api/bkn/load", async (req, res) => {
|
|
125
|
+
try {
|
|
126
|
+
const bodyStr = await readBody(req);
|
|
127
|
+
const { knId } = JSON.parse(bodyStr);
|
|
128
|
+
if (!knId) {
|
|
129
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
130
|
+
res.end(JSON.stringify({ error: "knId required" }));
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
console.error(`Loading schema for KN ${knId}...`);
|
|
134
|
+
const t = await freshToken();
|
|
135
|
+
const meta = await loadExploreMetaWithRetry(t, knId, businessDomain);
|
|
136
|
+
console.error(`Loaded: ${meta.objectTypes.length} OTs, ${meta.relationTypes.length} RTs`);
|
|
137
|
+
// Replace BKN routes with new KN's routes
|
|
138
|
+
for (const key of [...routes.keys()]) {
|
|
139
|
+
if (key.startsWith("GET /api/bkn/") || key.startsWith("POST /api/bkn/")) {
|
|
140
|
+
if (key !== "POST /api/bkn/load")
|
|
141
|
+
routes.delete(key);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
const newRoutes = registerBknRoutes(meta, freshToken, businessDomain);
|
|
145
|
+
for (const [key, handler] of newRoutes)
|
|
146
|
+
routes.set(key, handler);
|
|
147
|
+
bknMeta = meta;
|
|
148
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
149
|
+
res.end(JSON.stringify({ ok: true }));
|
|
150
|
+
}
|
|
151
|
+
catch (err) {
|
|
152
|
+
console.error("Failed to load KN:", err.message || err);
|
|
153
|
+
res.writeHead(500, { "Content-Type": "application/json" });
|
|
154
|
+
res.end(JSON.stringify({ error: String(err.message || err) }));
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
// Chat routes
|
|
158
|
+
const chatRoutes = registerChatRoutes(freshToken, businessDomain);
|
|
159
|
+
for (const [key, handler] of chatRoutes)
|
|
160
|
+
routes.set(key, handler);
|
|
161
|
+
// Vega routes
|
|
162
|
+
const vegaRoutes = registerVegaRoutes(freshToken, businessDomain);
|
|
163
|
+
for (const [key, handler] of vegaRoutes)
|
|
164
|
+
routes.set(key, handler);
|
|
165
|
+
// 3. Resolve template directory
|
|
166
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
167
|
+
const __dirname = join(__filename, "..");
|
|
168
|
+
const templateDir = join(__dirname, "..", "templates", "explorer");
|
|
169
|
+
// 4. Create HTTP server
|
|
170
|
+
const server = createServer((req, res) => {
|
|
171
|
+
const url = new URL(req.url || "/", `http://localhost:${opts.port}`);
|
|
172
|
+
const method = req.method || "GET";
|
|
173
|
+
const pathname = url.pathname;
|
|
174
|
+
// API route matching
|
|
175
|
+
const routeKey = `${method} ${pathname}`;
|
|
176
|
+
const handler = routes.get(routeKey);
|
|
177
|
+
if (handler) {
|
|
178
|
+
handler(req, res);
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
// Static file serving
|
|
182
|
+
let filePath = pathname === "/" ? "/index.html" : pathname;
|
|
183
|
+
const fullPath = join(templateDir, filePath);
|
|
184
|
+
// Security: prevent directory traversal
|
|
185
|
+
if (!fullPath.startsWith(templateDir)) {
|
|
186
|
+
res.writeHead(403);
|
|
187
|
+
res.end("Forbidden");
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
if (existsSync(fullPath)) {
|
|
191
|
+
const ext = extname(fullPath);
|
|
192
|
+
const contentType = MIME[ext] || "application/octet-stream";
|
|
193
|
+
const content = readFileSync(fullPath);
|
|
194
|
+
res.writeHead(200, { "Content-Type": contentType });
|
|
195
|
+
res.end(content);
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
// SPA fallback: serve index.html for unknown routes
|
|
199
|
+
const indexPath = join(templateDir, "index.html");
|
|
200
|
+
if (existsSync(indexPath)) {
|
|
201
|
+
const content = readFileSync(indexPath);
|
|
202
|
+
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
203
|
+
res.end(content);
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
res.writeHead(404);
|
|
207
|
+
res.end("Not Found");
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
// 5. Start listening
|
|
212
|
+
server.listen(opts.port, () => {
|
|
213
|
+
const initialHash = opts.knId ? `#/bkn/${opts.knId}` :
|
|
214
|
+
opts.agentId ? `#/chat/${opts.agentId}` : "";
|
|
215
|
+
const url = `http://localhost:${opts.port}/${initialHash}`;
|
|
216
|
+
console.error(`\nKWeaver Explorer running at ${url}\n`);
|
|
217
|
+
console.error("Press Ctrl+C to stop.\n");
|
|
218
|
+
// 6. Open browser
|
|
219
|
+
if (opts.open) {
|
|
220
|
+
try {
|
|
221
|
+
const platform = process.platform;
|
|
222
|
+
if (platform === "darwin")
|
|
223
|
+
execSync(`open "${url}"`);
|
|
224
|
+
else if (platform === "win32")
|
|
225
|
+
execSync(`start "" "${url}"`);
|
|
226
|
+
else
|
|
227
|
+
execSync(`xdg-open "${url}"`);
|
|
228
|
+
}
|
|
229
|
+
catch { /* ignore browser open failures */ }
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
// 7. Ctrl+C handling
|
|
233
|
+
await new Promise((resolve) => {
|
|
234
|
+
process.on("SIGINT", () => {
|
|
235
|
+
console.error("\nShutting down...");
|
|
236
|
+
server.close(() => resolve());
|
|
237
|
+
});
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
export async function runExploreCommand(args) {
|
|
241
|
+
let opts;
|
|
242
|
+
try {
|
|
243
|
+
opts = parseExploreArgs(args);
|
|
244
|
+
}
|
|
245
|
+
catch (err) {
|
|
246
|
+
if (err?.message === "help") {
|
|
247
|
+
printExploreHelp();
|
|
248
|
+
return 0;
|
|
249
|
+
}
|
|
250
|
+
throw err;
|
|
251
|
+
}
|
|
252
|
+
// Acquire token
|
|
253
|
+
const token = await ensureValidToken();
|
|
254
|
+
const businessDomain = opts.businessDomain || resolveBusinessDomain();
|
|
255
|
+
// Start the server
|
|
256
|
+
await startServer(opts, token, businessDomain);
|
|
257
|
+
return 0;
|
|
258
|
+
}
|
|
@@ -19,6 +19,8 @@ export interface DagBodyOptions {
|
|
|
19
19
|
tableExist: boolean;
|
|
20
20
|
data: Array<Record<string, string | null>>;
|
|
21
21
|
fieldMappings: FieldMapping[];
|
|
22
|
+
/** When true on the first batch (`tableExist` false), use overwrite to drop/recreate table before import. */
|
|
23
|
+
recreate?: boolean;
|
|
22
24
|
}
|
|
23
25
|
/**
|
|
24
26
|
* Read a CSV file and return its headers and rows.
|
|
@@ -80,8 +80,9 @@ export function buildFieldMappings(headers) {
|
|
|
80
80
|
* The DAG has two steps: a manual trigger and the database write.
|
|
81
81
|
*/
|
|
82
82
|
export function buildDagBody(options) {
|
|
83
|
-
const { datasourceId, datasourceType, tableName, tableExist, data, fieldMappings } = options;
|
|
83
|
+
const { datasourceId, datasourceType, tableName, tableExist, data, fieldMappings, recreate } = options;
|
|
84
84
|
const ts = Date.now();
|
|
85
|
+
const operateType = tableExist ? "append" : recreate ? "overwrite" : "append";
|
|
85
86
|
const triggerStep = {
|
|
86
87
|
id: "step-trigger",
|
|
87
88
|
title: "Trigger",
|
|
@@ -97,7 +98,7 @@ export function buildDagBody(options) {
|
|
|
97
98
|
datasource_id: datasourceId,
|
|
98
99
|
table_name: tableName,
|
|
99
100
|
table_exist: tableExist,
|
|
100
|
-
operate_type:
|
|
101
|
+
operate_type: operateType,
|
|
101
102
|
data,
|
|
102
103
|
sync_model_fields: fieldMappings,
|
|
103
104
|
},
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type SkillStatus } from "../api/skills.js";
|
|
2
|
+
interface BaseOptions {
|
|
3
|
+
businessDomain: string;
|
|
4
|
+
pretty: boolean;
|
|
5
|
+
}
|
|
6
|
+
interface ListOptions extends BaseOptions {
|
|
7
|
+
page: number;
|
|
8
|
+
pageSize: number;
|
|
9
|
+
all: boolean;
|
|
10
|
+
name?: string;
|
|
11
|
+
source?: string;
|
|
12
|
+
status?: SkillStatus;
|
|
13
|
+
createUser?: string;
|
|
14
|
+
sortBy?: "create_time" | "update_time" | "name";
|
|
15
|
+
sortOrder?: "asc" | "desc";
|
|
16
|
+
}
|
|
17
|
+
interface RegisterOptions extends BaseOptions {
|
|
18
|
+
contentFile?: string;
|
|
19
|
+
zipFile?: string;
|
|
20
|
+
source?: string;
|
|
21
|
+
extendInfo?: Record<string, unknown>;
|
|
22
|
+
}
|
|
23
|
+
export declare function parseSkillListArgs(args: string[]): ListOptions;
|
|
24
|
+
export declare function parseSkillRegisterArgs(args: string[]): RegisterOptions;
|
|
25
|
+
export declare function runSkillCommand(args: string[]): Promise<number>;
|
|
26
|
+
export {};
|