@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.
Files changed (95) hide show
  1. package/README.md +25 -2
  2. package/README.zh.md +24 -1
  3. package/dist/api/agent-chat.d.ts +8 -2
  4. package/dist/api/agent-chat.js +150 -44
  5. package/dist/api/agent-list.d.ts +35 -0
  6. package/dist/api/agent-list.js +95 -21
  7. package/dist/api/bkn-backend.d.ts +60 -0
  8. package/dist/api/bkn-backend.js +103 -10
  9. package/dist/api/business-domains.js +9 -5
  10. package/dist/api/context-loader.js +4 -1
  11. package/dist/api/conversations.d.ts +6 -3
  12. package/dist/api/conversations.js +29 -35
  13. package/dist/api/dataflow.js +1 -10
  14. package/dist/api/dataflow2.d.ts +95 -0
  15. package/dist/api/dataflow2.js +80 -0
  16. package/dist/api/datasources.js +1 -10
  17. package/dist/api/dataviews.js +1 -10
  18. package/dist/api/headers.d.ts +11 -0
  19. package/dist/api/headers.js +30 -0
  20. package/dist/api/knowledge-networks.d.ts +41 -0
  21. package/dist/api/knowledge-networks.js +69 -22
  22. package/dist/api/ontology-query.d.ts +14 -1
  23. package/dist/api/ontology-query.js +63 -49
  24. package/dist/api/semantic-search.js +2 -12
  25. package/dist/api/skills.d.ts +141 -0
  26. package/dist/api/skills.js +208 -0
  27. package/dist/api/vega.d.ts +54 -7
  28. package/dist/api/vega.js +112 -25
  29. package/dist/auth/oauth.d.ts +5 -1
  30. package/dist/auth/oauth.js +351 -95
  31. package/dist/cli.js +49 -5
  32. package/dist/client.d.ts +12 -0
  33. package/dist/client.js +52 -8
  34. package/dist/commands/agent.d.ts +33 -1
  35. package/dist/commands/agent.js +721 -49
  36. package/dist/commands/auth.js +226 -55
  37. package/dist/commands/bkn-ops.d.ts +77 -0
  38. package/dist/commands/bkn-ops.js +1056 -0
  39. package/dist/commands/bkn-query.d.ts +14 -0
  40. package/dist/commands/bkn-query.js +370 -0
  41. package/dist/commands/bkn-schema.d.ts +135 -0
  42. package/dist/commands/bkn-schema.js +1483 -0
  43. package/dist/commands/bkn-utils.d.ts +36 -0
  44. package/dist/commands/bkn-utils.js +102 -0
  45. package/dist/commands/bkn.d.ts +7 -113
  46. package/dist/commands/bkn.js +175 -2429
  47. package/dist/commands/call.js +8 -5
  48. package/dist/commands/dataflow.d.ts +1 -0
  49. package/dist/commands/dataflow.js +251 -0
  50. package/dist/commands/dataview.d.ts +7 -0
  51. package/dist/commands/dataview.js +38 -2
  52. package/dist/commands/ds.d.ts +1 -0
  53. package/dist/commands/ds.js +8 -1
  54. package/dist/commands/explore-bkn.d.ts +79 -0
  55. package/dist/commands/explore-bkn.js +273 -0
  56. package/dist/commands/explore-chat.d.ts +3 -0
  57. package/dist/commands/explore-chat.js +193 -0
  58. package/dist/commands/explore-vega.d.ts +3 -0
  59. package/dist/commands/explore-vega.js +71 -0
  60. package/dist/commands/explore.d.ts +9 -0
  61. package/dist/commands/explore.js +258 -0
  62. package/dist/commands/import-csv.d.ts +2 -0
  63. package/dist/commands/import-csv.js +3 -2
  64. package/dist/commands/skill.d.ts +26 -0
  65. package/dist/commands/skill.js +524 -0
  66. package/dist/commands/vega.js +372 -117
  67. package/dist/config/jwt.d.ts +6 -0
  68. package/dist/config/jwt.js +21 -0
  69. package/dist/config/no-auth.d.ts +3 -0
  70. package/dist/config/no-auth.js +5 -0
  71. package/dist/config/store.d.ts +45 -5
  72. package/dist/config/store.js +385 -30
  73. package/dist/index.d.ts +6 -1
  74. package/dist/index.js +5 -1
  75. package/dist/kweaver.d.ts +5 -0
  76. package/dist/kweaver.js +32 -2
  77. package/dist/resources/bkn.d.ts +4 -0
  78. package/dist/resources/bkn.js +6 -3
  79. package/dist/resources/conversations.d.ts +5 -2
  80. package/dist/resources/conversations.js +17 -3
  81. package/dist/resources/knowledge-networks.js +3 -8
  82. package/dist/resources/skills.d.ts +47 -0
  83. package/dist/resources/skills.js +47 -0
  84. package/dist/resources/vega.d.ts +11 -6
  85. package/dist/resources/vega.js +37 -10
  86. package/dist/templates/explorer/app.js +136 -0
  87. package/dist/templates/explorer/bkn.js +747 -0
  88. package/dist/templates/explorer/chat.js +980 -0
  89. package/dist/templates/explorer/dashboard.js +82 -0
  90. package/dist/templates/explorer/index.html +35 -0
  91. package/dist/templates/explorer/style.css +2440 -0
  92. package/dist/templates/explorer/vega.js +291 -0
  93. package/dist/utils/http.d.ts +3 -0
  94. package/dist/utils/http.js +37 -1
  95. 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: "append",
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 {};