openxgen 0.3.0 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -4
- package/dist/index.js +1556 -1037
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -157,60 +157,8 @@ var init_store = __esm({
|
|
|
157
157
|
}
|
|
158
158
|
});
|
|
159
159
|
|
|
160
|
-
// src/api/auth.ts
|
|
161
|
-
var auth_exports = {};
|
|
162
|
-
__export(auth_exports, {
|
|
163
|
-
apiLogin: () => apiLogin,
|
|
164
|
-
apiRefresh: () => apiRefresh,
|
|
165
|
-
apiValidate: () => apiValidate
|
|
166
|
-
});
|
|
167
|
-
import axios2 from "axios";
|
|
168
|
-
import { createHash } from "crypto";
|
|
169
|
-
async function apiLogin(email, password) {
|
|
170
|
-
const server = getServer();
|
|
171
|
-
if (!server) throw new Error("\uC11C\uBC84\uAC00 \uC124\uC815\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4");
|
|
172
|
-
const hashedPassword = createHash("sha256").update(password).digest("hex");
|
|
173
|
-
const res = await axios2.post(`${server}/api/auth/login`, {
|
|
174
|
-
email,
|
|
175
|
-
password: hashedPassword
|
|
176
|
-
});
|
|
177
|
-
return res.data;
|
|
178
|
-
}
|
|
179
|
-
async function apiValidate(accessToken) {
|
|
180
|
-
const server = getServer();
|
|
181
|
-
if (!server) throw new Error("\uC11C\uBC84\uAC00 \uC124\uC815\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4");
|
|
182
|
-
const res = await axios2.get(`${server}/api/auth/validate`, {
|
|
183
|
-
headers: { Authorization: `Bearer ${accessToken}` }
|
|
184
|
-
});
|
|
185
|
-
return res.data;
|
|
186
|
-
}
|
|
187
|
-
async function apiRefresh(refreshToken) {
|
|
188
|
-
const server = getServer();
|
|
189
|
-
if (!server) throw new Error("\uC11C\uBC84\uAC00 \uC124\uC815\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4");
|
|
190
|
-
const res = await axios2.post(`${server}/api/auth/refresh`, {
|
|
191
|
-
refresh_token: refreshToken
|
|
192
|
-
});
|
|
193
|
-
return res.data;
|
|
194
|
-
}
|
|
195
|
-
var init_auth = __esm({
|
|
196
|
-
"src/api/auth.ts"() {
|
|
197
|
-
"use strict";
|
|
198
|
-
init_store();
|
|
199
|
-
}
|
|
200
|
-
});
|
|
201
|
-
|
|
202
|
-
// src/index.ts
|
|
203
|
-
import { Command } from "commander";
|
|
204
|
-
import chalk14 from "chalk";
|
|
205
|
-
|
|
206
|
-
// src/commands/config.ts
|
|
207
|
-
init_store();
|
|
208
|
-
import chalk2 from "chalk";
|
|
209
|
-
|
|
210
160
|
// src/api/client.ts
|
|
211
|
-
init_store();
|
|
212
161
|
import axios from "axios";
|
|
213
|
-
var client = null;
|
|
214
162
|
function getClient() {
|
|
215
163
|
if (client) return client;
|
|
216
164
|
const server = getServer();
|
|
@@ -266,6 +214,14 @@ function getClient() {
|
|
|
266
214
|
function resetClient() {
|
|
267
215
|
client = null;
|
|
268
216
|
}
|
|
217
|
+
var client;
|
|
218
|
+
var init_client = __esm({
|
|
219
|
+
"src/api/client.ts"() {
|
|
220
|
+
"use strict";
|
|
221
|
+
init_store();
|
|
222
|
+
client = null;
|
|
223
|
+
}
|
|
224
|
+
});
|
|
269
225
|
|
|
270
226
|
// src/utils/format.ts
|
|
271
227
|
import chalk from "chalk";
|
|
@@ -313,254 +269,139 @@ function formatDate(dateStr) {
|
|
|
313
269
|
return dateStr;
|
|
314
270
|
}
|
|
315
271
|
}
|
|
272
|
+
var init_format = __esm({
|
|
273
|
+
"src/utils/format.ts"() {
|
|
274
|
+
"use strict";
|
|
275
|
+
}
|
|
276
|
+
});
|
|
316
277
|
|
|
317
|
-
// src/
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
278
|
+
// src/api/auth.ts
|
|
279
|
+
var auth_exports = {};
|
|
280
|
+
__export(auth_exports, {
|
|
281
|
+
apiLogin: () => apiLogin,
|
|
282
|
+
apiRefresh: () => apiRefresh,
|
|
283
|
+
apiValidate: () => apiValidate
|
|
284
|
+
});
|
|
285
|
+
import axios2 from "axios";
|
|
286
|
+
import { createHash } from "crypto";
|
|
287
|
+
async function apiLogin(email, password) {
|
|
288
|
+
const server = getServer();
|
|
289
|
+
if (!server) throw new Error("\uC11C\uBC84\uAC00 \uC124\uC815\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4");
|
|
290
|
+
const hashedPassword = createHash("sha256").update(password).digest("hex");
|
|
291
|
+
const res = await axios2.post(`${server}/api/auth/login`, {
|
|
292
|
+
email,
|
|
293
|
+
password: hashedPassword
|
|
328
294
|
});
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
}
|
|
295
|
+
return res.data;
|
|
296
|
+
}
|
|
297
|
+
async function apiValidate(accessToken) {
|
|
298
|
+
const server = getServer();
|
|
299
|
+
if (!server) throw new Error("\uC11C\uBC84\uAC00 \uC124\uC815\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4");
|
|
300
|
+
const res = await axios2.get(`${server}/api/auth/validate`, {
|
|
301
|
+
headers: { Authorization: `Bearer ${accessToken}` }
|
|
337
302
|
});
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
printKeyValue("\uC2A4\uD2B8\uB9BC \uB85C\uADF8", String(cfg.streamLogs));
|
|
346
|
-
console.log();
|
|
303
|
+
return res.data;
|
|
304
|
+
}
|
|
305
|
+
async function apiRefresh(refreshToken) {
|
|
306
|
+
const server = getServer();
|
|
307
|
+
if (!server) throw new Error("\uC11C\uBC84\uAC00 \uC124\uC815\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4");
|
|
308
|
+
const res = await axios2.post(`${server}/api/auth/refresh`, {
|
|
309
|
+
refresh_token: refreshToken
|
|
347
310
|
});
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
311
|
+
return res.data;
|
|
312
|
+
}
|
|
313
|
+
var init_auth = __esm({
|
|
314
|
+
"src/api/auth.ts"() {
|
|
315
|
+
"use strict";
|
|
316
|
+
init_store();
|
|
317
|
+
}
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
// src/api/workflow.ts
|
|
321
|
+
async function listWorkflows(userId) {
|
|
322
|
+
const client2 = getClient();
|
|
323
|
+
const params = {};
|
|
324
|
+
if (userId) params.user_id = userId;
|
|
325
|
+
const res = await client2.get("/api/workflow/list", { params });
|
|
326
|
+
return res.data.workflows ?? res.data;
|
|
327
|
+
}
|
|
328
|
+
async function getWorkflowDetail(workflowId) {
|
|
329
|
+
const client2 = getClient();
|
|
330
|
+
const res = await client2.get(`/api/workflow/load/${workflowId}`);
|
|
331
|
+
return res.data;
|
|
332
|
+
}
|
|
333
|
+
async function getWorkflowListDetail() {
|
|
334
|
+
const client2 = getClient();
|
|
335
|
+
const res = await client2.get("/api/workflow/list/detail");
|
|
336
|
+
return res.data;
|
|
337
|
+
}
|
|
338
|
+
async function executeWorkflowStream(request) {
|
|
339
|
+
const client2 = getClient();
|
|
340
|
+
const res = await client2.post("/api/workflow/execute/based_id/stream", request, {
|
|
341
|
+
responseType: "stream",
|
|
342
|
+
headers: {
|
|
343
|
+
Accept: "text/event-stream"
|
|
354
344
|
}
|
|
355
|
-
const parsed = key === "streamLogs" ? value === "true" : value;
|
|
356
|
-
setConfig({ [key]: parsed });
|
|
357
|
-
printSuccess(`${key} = ${value}`);
|
|
358
345
|
});
|
|
346
|
+
return res.data;
|
|
347
|
+
}
|
|
348
|
+
async function getIOLogs(workflowId, limit = 20) {
|
|
349
|
+
const client2 = getClient();
|
|
350
|
+
const params = { limit };
|
|
351
|
+
if (workflowId) params.workflow_id = workflowId;
|
|
352
|
+
const res = await client2.get("/api/workflow/io_logs", { params });
|
|
353
|
+
return res.data;
|
|
359
354
|
}
|
|
355
|
+
var init_workflow = __esm({
|
|
356
|
+
"src/api/workflow.ts"() {
|
|
357
|
+
"use strict";
|
|
358
|
+
init_client();
|
|
359
|
+
}
|
|
360
|
+
});
|
|
360
361
|
|
|
361
|
-
// src/commands/
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
} else if (c === "\x7F" || c === "\b") {
|
|
389
|
-
if (password.length > 0) {
|
|
390
|
-
password = password.slice(0, -1);
|
|
391
|
-
process.stdout.write("\b \b");
|
|
392
|
-
}
|
|
393
|
-
} else {
|
|
394
|
-
password += c;
|
|
395
|
-
process.stdout.write("*");
|
|
396
|
-
}
|
|
397
|
-
};
|
|
398
|
-
stdin.on("data", onData);
|
|
362
|
+
// src/commands/workflow/list.ts
|
|
363
|
+
var list_exports = {};
|
|
364
|
+
__export(list_exports, {
|
|
365
|
+
workflowList: () => workflowList
|
|
366
|
+
});
|
|
367
|
+
import chalk4 from "chalk";
|
|
368
|
+
async function workflowList(opts) {
|
|
369
|
+
requireAuth();
|
|
370
|
+
try {
|
|
371
|
+
if (opts.detail) {
|
|
372
|
+
const workflows = await getWorkflowListDetail();
|
|
373
|
+
if (!workflows || workflows.length === 0) {
|
|
374
|
+
console.log(chalk4.yellow("\n\uC6CC\uD06C\uD50C\uB85C\uC6B0\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.\n"));
|
|
375
|
+
return;
|
|
376
|
+
}
|
|
377
|
+
printHeader(`\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uBAA9\uB85D (${workflows.length}\uAC1C)`);
|
|
378
|
+
console.log();
|
|
379
|
+
printTable(
|
|
380
|
+
["#", "ID", "\uC774\uB984", "\uBC30\uD3EC", "\uC5C5\uB370\uC774\uD2B8"],
|
|
381
|
+
workflows.map((w, i) => [
|
|
382
|
+
String(i + 1),
|
|
383
|
+
(w.workflow_id ?? w.id ?? "-").slice(0, 12),
|
|
384
|
+
truncate(w.workflow_name ?? "-", 30),
|
|
385
|
+
w.deploy_status === "deployed" ? chalk4.green("\uBC30\uD3EC\uB428") : chalk4.gray("\uBBF8\uBC30\uD3EC"),
|
|
386
|
+
formatDate(w.updated_at)
|
|
387
|
+
])
|
|
388
|
+
);
|
|
399
389
|
} else {
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
if (!email) {
|
|
416
|
-
email = await prompt(chalk3.white("\uC774\uBA54\uC77C: "));
|
|
417
|
-
}
|
|
418
|
-
if (!password) {
|
|
419
|
-
password = await prompt(chalk3.white("\uBE44\uBC00\uBC88\uD638: "), true);
|
|
420
|
-
}
|
|
421
|
-
if (!email || !password) {
|
|
422
|
-
printError("\uC774\uBA54\uC77C\uACFC \uBE44\uBC00\uBC88\uD638\uB97C \uBAA8\uB450 \uC785\uB825\uD558\uC138\uC694");
|
|
423
|
-
process.exit(1);
|
|
424
|
-
}
|
|
425
|
-
try {
|
|
426
|
-
const result = await apiLogin(email, password);
|
|
427
|
-
if (result.success && result.access_token) {
|
|
428
|
-
setAuth({
|
|
429
|
-
accessToken: result.access_token,
|
|
430
|
-
refreshToken: result.refresh_token ?? "",
|
|
431
|
-
userId: result.user_id ?? "",
|
|
432
|
-
username: result.username ?? "",
|
|
433
|
-
isAdmin: false,
|
|
434
|
-
expiresAt: null
|
|
435
|
-
});
|
|
436
|
-
console.log();
|
|
437
|
-
printSuccess(`\uB85C\uADF8\uC778 \uC131\uACF5! ${chalk3.bold(result.username ?? email)}`);
|
|
438
|
-
} else {
|
|
439
|
-
printError(result.message || "\uB85C\uADF8\uC778 \uC2E4\uD328");
|
|
440
|
-
process.exit(1);
|
|
441
|
-
}
|
|
442
|
-
} catch (err) {
|
|
443
|
-
const msg = err?.response?.data?.message ?? err?.response?.data?.detail ?? err.message;
|
|
444
|
-
printError(`\uB85C\uADF8\uC778 \uC2E4\uD328: ${msg}`);
|
|
445
|
-
process.exit(1);
|
|
446
|
-
}
|
|
447
|
-
});
|
|
448
|
-
program2.command("logout").description("\uB85C\uADF8\uC544\uC6C3").action(async () => {
|
|
449
|
-
const { clearAuth: clearAuth2 } = await Promise.resolve().then(() => (init_store(), store_exports));
|
|
450
|
-
clearAuth2();
|
|
451
|
-
printSuccess("\uB85C\uADF8\uC544\uC6C3 \uC644\uB8CC");
|
|
452
|
-
});
|
|
453
|
-
program2.command("whoami").description("\uD604\uC7AC \uB85C\uADF8\uC778\uB41C \uC0AC\uC6A9\uC790 \uC815\uBCF4").action(async () => {
|
|
454
|
-
const auth = getAuth();
|
|
455
|
-
if (!auth) {
|
|
456
|
-
printError("\uB85C\uADF8\uC778\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. xgen login \uC2E4\uD589\uD558\uC138\uC694");
|
|
457
|
-
process.exit(1);
|
|
458
|
-
}
|
|
459
|
-
const server = requireServer();
|
|
460
|
-
console.log(chalk3.bold("\n\uD604\uC7AC \uC0AC\uC6A9\uC790"));
|
|
461
|
-
console.log(chalk3.gray("\u2500".repeat(30)));
|
|
462
|
-
console.log(` ${chalk3.gray("\uC11C\uBC84:")} ${server}`);
|
|
463
|
-
console.log(` ${chalk3.gray("\uC0AC\uC6A9\uC790:")} ${chalk3.bold(auth.username)}`);
|
|
464
|
-
console.log(` ${chalk3.gray("User ID:")} ${auth.userId}`);
|
|
465
|
-
try {
|
|
466
|
-
const { apiValidate: apiValidate2 } = await Promise.resolve().then(() => (init_auth(), auth_exports));
|
|
467
|
-
const result = await apiValidate2(auth.accessToken);
|
|
468
|
-
if (result.valid) {
|
|
469
|
-
console.log(` ${chalk3.gray("\uC0C1\uD0DC:")} ${chalk3.green("\uD65C\uC131")}`);
|
|
470
|
-
if (result.is_admin) {
|
|
471
|
-
console.log(` ${chalk3.gray("\uAD8C\uD55C:")} ${chalk3.yellow("\uAD00\uB9AC\uC790")}`);
|
|
472
|
-
}
|
|
473
|
-
if (result.user_type) {
|
|
474
|
-
console.log(` ${chalk3.gray("\uC720\uD615:")} ${result.user_type}`);
|
|
475
|
-
}
|
|
476
|
-
} else {
|
|
477
|
-
console.log(` ${chalk3.gray("\uC0C1\uD0DC:")} ${chalk3.red("\uD1A0\uD070 \uB9CC\uB8CC")}`);
|
|
478
|
-
}
|
|
479
|
-
} catch {
|
|
480
|
-
console.log(` ${chalk3.gray("\uC0C1\uD0DC:")} ${chalk3.yellow("\uAC80\uC99D \uBD88\uAC00 (\uC11C\uBC84 \uC5F0\uACB0 \uC2E4\uD328)")}`);
|
|
481
|
-
}
|
|
482
|
-
console.log();
|
|
483
|
-
});
|
|
484
|
-
}
|
|
485
|
-
|
|
486
|
-
// src/commands/workflow/list.ts
|
|
487
|
-
init_store();
|
|
488
|
-
import chalk4 from "chalk";
|
|
489
|
-
|
|
490
|
-
// src/api/workflow.ts
|
|
491
|
-
async function listWorkflows(userId) {
|
|
492
|
-
const client2 = getClient();
|
|
493
|
-
const params = {};
|
|
494
|
-
if (userId) params.user_id = userId;
|
|
495
|
-
const res = await client2.get("/api/workflow/list", { params });
|
|
496
|
-
return res.data.workflows ?? res.data;
|
|
497
|
-
}
|
|
498
|
-
async function getWorkflowDetail(workflowId) {
|
|
499
|
-
const client2 = getClient();
|
|
500
|
-
const res = await client2.get(`/api/workflow/load/${workflowId}`);
|
|
501
|
-
return res.data;
|
|
502
|
-
}
|
|
503
|
-
async function getWorkflowListDetail() {
|
|
504
|
-
const client2 = getClient();
|
|
505
|
-
const res = await client2.get("/api/workflow/list/detail");
|
|
506
|
-
return res.data;
|
|
507
|
-
}
|
|
508
|
-
async function executeWorkflowStream(request) {
|
|
509
|
-
const client2 = getClient();
|
|
510
|
-
const res = await client2.post("/api/workflow/execute/based_id/stream", request, {
|
|
511
|
-
responseType: "stream",
|
|
512
|
-
headers: {
|
|
513
|
-
Accept: "text/event-stream"
|
|
514
|
-
}
|
|
515
|
-
});
|
|
516
|
-
return res.data;
|
|
517
|
-
}
|
|
518
|
-
async function getIOLogs(workflowId, limit = 20) {
|
|
519
|
-
const client2 = getClient();
|
|
520
|
-
const params = { limit };
|
|
521
|
-
if (workflowId) params.workflow_id = workflowId;
|
|
522
|
-
const res = await client2.get("/api/workflow/io_logs", { params });
|
|
523
|
-
return res.data;
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
// src/commands/workflow/list.ts
|
|
527
|
-
async function workflowList(opts) {
|
|
528
|
-
requireAuth();
|
|
529
|
-
try {
|
|
530
|
-
if (opts.detail) {
|
|
531
|
-
const workflows = await getWorkflowListDetail();
|
|
532
|
-
if (!workflows || workflows.length === 0) {
|
|
533
|
-
console.log(chalk4.yellow("\n\uC6CC\uD06C\uD50C\uB85C\uC6B0\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.\n"));
|
|
534
|
-
return;
|
|
535
|
-
}
|
|
536
|
-
printHeader(`\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uBAA9\uB85D (${workflows.length}\uAC1C)`);
|
|
537
|
-
console.log();
|
|
538
|
-
printTable(
|
|
539
|
-
["#", "ID", "\uC774\uB984", "\uBC30\uD3EC", "\uC5C5\uB370\uC774\uD2B8"],
|
|
540
|
-
workflows.map((w, i) => [
|
|
541
|
-
String(i + 1),
|
|
542
|
-
(w.workflow_id ?? w.id ?? "-").slice(0, 12),
|
|
543
|
-
truncate(w.workflow_name ?? "-", 30),
|
|
544
|
-
w.deploy_status === "deployed" ? chalk4.green("\uBC30\uD3EC\uB428") : chalk4.gray("\uBBF8\uBC30\uD3EC"),
|
|
545
|
-
formatDate(w.updated_at)
|
|
546
|
-
])
|
|
547
|
-
);
|
|
548
|
-
} else {
|
|
549
|
-
const workflows = await listWorkflows();
|
|
550
|
-
if (!workflows || workflows.length === 0) {
|
|
551
|
-
console.log(chalk4.yellow("\n\uC6CC\uD06C\uD50C\uB85C\uC6B0\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.\n"));
|
|
552
|
-
return;
|
|
553
|
-
}
|
|
554
|
-
printHeader(`\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uBAA9\uB85D (${workflows.length}\uAC1C)`);
|
|
555
|
-
console.log();
|
|
556
|
-
printTable(
|
|
557
|
-
["#", "ID", "\uC774\uB984"],
|
|
558
|
-
workflows.map((w, i) => [
|
|
559
|
-
String(i + 1),
|
|
560
|
-
(w.workflow_id ?? w.id ?? "-").slice(0, 12),
|
|
561
|
-
w.workflow_name ?? "-"
|
|
562
|
-
])
|
|
563
|
-
);
|
|
390
|
+
const workflows = await listWorkflows();
|
|
391
|
+
if (!workflows || workflows.length === 0) {
|
|
392
|
+
console.log(chalk4.yellow("\n\uC6CC\uD06C\uD50C\uB85C\uC6B0\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.\n"));
|
|
393
|
+
return;
|
|
394
|
+
}
|
|
395
|
+
printHeader(`\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uBAA9\uB85D (${workflows.length}\uAC1C)`);
|
|
396
|
+
console.log();
|
|
397
|
+
printTable(
|
|
398
|
+
["#", "ID", "\uC774\uB984"],
|
|
399
|
+
workflows.map((w, i) => [
|
|
400
|
+
String(i + 1),
|
|
401
|
+
(w.workflow_id ?? w.id ?? "-").slice(0, 12),
|
|
402
|
+
w.workflow_name ?? "-"
|
|
403
|
+
])
|
|
404
|
+
);
|
|
564
405
|
}
|
|
565
406
|
console.log();
|
|
566
407
|
} catch (err) {
|
|
@@ -569,47 +410,14 @@ async function workflowList(opts) {
|
|
|
569
410
|
process.exit(1);
|
|
570
411
|
}
|
|
571
412
|
}
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
try {
|
|
579
|
-
const detail = await getWorkflowDetail(workflowId);
|
|
580
|
-
printHeader(`\uC6CC\uD06C\uD50C\uB85C\uC6B0: ${detail.workflow_name ?? workflowId}`);
|
|
581
|
-
console.log();
|
|
582
|
-
printKeyValue("ID", detail.id);
|
|
583
|
-
printKeyValue("\uC774\uB984", detail.workflow_name);
|
|
584
|
-
printKeyValue("\uC124\uBA85", detail.description ?? "(\uC5C6\uC74C)");
|
|
585
|
-
if (detail.nodes && Array.isArray(detail.nodes)) {
|
|
586
|
-
console.log();
|
|
587
|
-
console.log(chalk5.bold(" \uB178\uB4DC \uAD6C\uC131:"));
|
|
588
|
-
for (const node of detail.nodes) {
|
|
589
|
-
const label = node.data?.label ?? node.id;
|
|
590
|
-
const type = node.data?.type ?? "unknown";
|
|
591
|
-
console.log(` ${chalk5.cyan("\u2022")} ${label} ${chalk5.gray(`(${type})`)}`);
|
|
592
|
-
}
|
|
593
|
-
}
|
|
594
|
-
if (detail.parameters && Object.keys(detail.parameters).length > 0) {
|
|
595
|
-
console.log();
|
|
596
|
-
console.log(chalk5.bold(" \uD30C\uB77C\uBBF8\uD130:"));
|
|
597
|
-
for (const [key, val] of Object.entries(detail.parameters)) {
|
|
598
|
-
console.log(` ${chalk5.gray(key)}: ${JSON.stringify(val)}`);
|
|
599
|
-
}
|
|
600
|
-
}
|
|
601
|
-
console.log();
|
|
602
|
-
} catch (err) {
|
|
603
|
-
const msg = err.message;
|
|
604
|
-
printError(`\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uC870\uD68C \uC2E4\uD328: ${msg}`);
|
|
605
|
-
process.exit(1);
|
|
413
|
+
var init_list = __esm({
|
|
414
|
+
"src/commands/workflow/list.ts"() {
|
|
415
|
+
"use strict";
|
|
416
|
+
init_store();
|
|
417
|
+
init_workflow();
|
|
418
|
+
init_format();
|
|
606
419
|
}
|
|
607
|
-
}
|
|
608
|
-
|
|
609
|
-
// src/commands/workflow/run.ts
|
|
610
|
-
init_store();
|
|
611
|
-
import chalk7 from "chalk";
|
|
612
|
-
import { randomUUID } from "crypto";
|
|
420
|
+
});
|
|
613
421
|
|
|
614
422
|
// src/utils/sse.ts
|
|
615
423
|
async function parseSSEStream(stream, onEvent, onDone, onError) {
|
|
@@ -661,233 +469,37 @@ async function parseSSEStream(stream, onEvent, onDone, onError) {
|
|
|
661
469
|
});
|
|
662
470
|
});
|
|
663
471
|
}
|
|
472
|
+
var init_sse = __esm({
|
|
473
|
+
"src/utils/sse.ts"() {
|
|
474
|
+
"use strict";
|
|
475
|
+
}
|
|
476
|
+
});
|
|
664
477
|
|
|
665
|
-
// src/
|
|
666
|
-
import
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
});
|
|
685
|
-
result = result.replace(INLINE_CODE_RE, (_m, code) => chalk6.cyan(`\`${code}\``));
|
|
686
|
-
result = result.replace(BOLD_RE, (_m, text2) => chalk6.bold(text2));
|
|
687
|
-
result = result.replace(HEADING_RE, (_m, hashes, text2) => {
|
|
688
|
-
if (hashes.length === 1) return chalk6.bold.underline(text2);
|
|
689
|
-
if (hashes.length === 2) return chalk6.bold(text2);
|
|
690
|
-
return chalk6.bold.dim(text2);
|
|
478
|
+
// src/commands/chat.ts
|
|
479
|
+
import chalk9 from "chalk";
|
|
480
|
+
import { createInterface as createInterface2 } from "readline";
|
|
481
|
+
import { randomUUID as randomUUID2 } from "crypto";
|
|
482
|
+
function printHelp() {
|
|
483
|
+
console.log(`
|
|
484
|
+
${chalk9.bold("\uC2AC\uB798\uC2DC \uCEE4\uB9E8\uB4DC")}
|
|
485
|
+
${chalk9.cyan("/workflows")} \uC6CC\uD06C\uD50C\uB85C\uC6B0 \uBAA9\uB85D \uBCF4\uAE30 & \uC804\uD658
|
|
486
|
+
${chalk9.cyan("/switch")} \uC6CC\uD06C\uD50C\uB85C\uC6B0 \uBC88\uD638\uB85C \uC804\uD658 (\uC608: /switch 3)
|
|
487
|
+
${chalk9.cyan("/history")} \uD604\uC7AC \uC138\uC158 \uB300\uD654 \uC774\uB825
|
|
488
|
+
${chalk9.cyan("/clear")} \uD654\uBA74 \uC9C0\uC6B0\uAE30
|
|
489
|
+
${chalk9.cyan("/info")} \uD604\uC7AC \uC5F0\uACB0 \uC815\uBCF4
|
|
490
|
+
${chalk9.cyan("/help")} \uC774 \uB3C4\uC6C0\uB9D0
|
|
491
|
+
${chalk9.cyan("/exit")} \uC885\uB8CC (Ctrl+C\uB3C4 \uAC00\uB2A5)
|
|
492
|
+
`);
|
|
493
|
+
}
|
|
494
|
+
async function promptLine(rl, promptStr) {
|
|
495
|
+
return new Promise((resolve) => {
|
|
496
|
+
rl.question(promptStr, (answer) => resolve(answer));
|
|
691
497
|
});
|
|
692
|
-
result = result.replace(LIST_RE, (_m, indent, text2) => `${indent}${chalk6.cyan("\u2022")} ${text2}`);
|
|
693
|
-
result = result.replace(LINK_RE, (_m, label, url) => `${chalk6.blue.underline(label)} ${chalk6.gray(`(${url})`)}`);
|
|
694
|
-
return result;
|
|
695
498
|
}
|
|
696
|
-
|
|
697
|
-
// src/commands/workflow/run.ts
|
|
698
|
-
async function workflowRun(workflowId, input, opts) {
|
|
499
|
+
async function chat(workflowId) {
|
|
699
500
|
const auth = requireAuth();
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
const detail = await getWorkflowDetail(workflowId);
|
|
703
|
-
workflowName = detail.workflow_name ?? workflowId;
|
|
704
|
-
} catch {
|
|
705
|
-
}
|
|
706
|
-
if (!input) {
|
|
707
|
-
if (opts.interactive || !process.stdin.isTTY) {
|
|
708
|
-
const { createInterface: createInterface7 } = await import("readline");
|
|
709
|
-
const rl = createInterface7({ input: process.stdin, output: process.stdout });
|
|
710
|
-
input = await new Promise((resolve) => {
|
|
711
|
-
rl.question(chalk7.cyan("\uC785\uB825> "), (answer) => {
|
|
712
|
-
rl.close();
|
|
713
|
-
resolve(answer.trim());
|
|
714
|
-
});
|
|
715
|
-
});
|
|
716
|
-
} else {
|
|
717
|
-
printError("\uC785\uB825\uAC12\uC774 \uD544\uC694\uD569\uB2C8\uB2E4. \uC0AC\uC6A9\uBC95:");
|
|
718
|
-
console.log(' xgen workflow run <id> "\uC785\uB825 \uD14D\uC2A4\uFFFD\uFFFD\uFFFD"');
|
|
719
|
-
console.log(" xgen workflow run -i <id>");
|
|
720
|
-
process.exit(1);
|
|
721
|
-
}
|
|
722
|
-
}
|
|
723
|
-
if (!input) {
|
|
724
|
-
printError("\uC785\uB825\uAC12\uC774 \uBE44\uC5B4\uC788\uC2B5\uB2C8\uB2E4");
|
|
725
|
-
process.exit(1);
|
|
726
|
-
}
|
|
727
|
-
const interactionId = `cli_${randomUUID().slice(0, 8)}`;
|
|
728
|
-
printHeader(`\uC2E4\uD589: ${workflowName}`);
|
|
729
|
-
printInfo(`\uC785\uB825: ${input}`);
|
|
730
|
-
console.log();
|
|
731
|
-
try {
|
|
732
|
-
const stream = await executeWorkflowStream({
|
|
733
|
-
workflow_id: workflowId,
|
|
734
|
-
workflow_name: workflowName,
|
|
735
|
-
input_data: input,
|
|
736
|
-
interaction_id: interactionId
|
|
737
|
-
});
|
|
738
|
-
let hasOutput = false;
|
|
739
|
-
let fullResponse = "";
|
|
740
|
-
await parseSSEStream(
|
|
741
|
-
stream,
|
|
742
|
-
(event) => {
|
|
743
|
-
switch (event.type) {
|
|
744
|
-
case "token":
|
|
745
|
-
if (event.content) {
|
|
746
|
-
if (!hasOutput) {
|
|
747
|
-
hasOutput = true;
|
|
748
|
-
console.log();
|
|
749
|
-
}
|
|
750
|
-
process.stdout.write(event.content);
|
|
751
|
-
fullResponse += event.content;
|
|
752
|
-
}
|
|
753
|
-
break;
|
|
754
|
-
case "log":
|
|
755
|
-
if (opts.logs && event.content) {
|
|
756
|
-
process.stderr.write(chalk7.gray(`[LOG] ${event.content}
|
|
757
|
-
`));
|
|
758
|
-
}
|
|
759
|
-
break;
|
|
760
|
-
case "node_status":
|
|
761
|
-
if (opts.logs) {
|
|
762
|
-
const nodeName = event.node_name ?? event.node_id ?? "?";
|
|
763
|
-
const status = event.status ?? "?";
|
|
764
|
-
process.stderr.write(
|
|
765
|
-
chalk7.gray(`[\uB178\uB4DC] ${nodeName}: ${status}
|
|
766
|
-
`)
|
|
767
|
-
);
|
|
768
|
-
}
|
|
769
|
-
break;
|
|
770
|
-
case "tool":
|
|
771
|
-
if (opts.logs) {
|
|
772
|
-
process.stderr.write(chalk7.gray(`[\uB3C4\uAD6C] ${JSON.stringify(event.data)}
|
|
773
|
-
`));
|
|
774
|
-
}
|
|
775
|
-
break;
|
|
776
|
-
case "complete":
|
|
777
|
-
break;
|
|
778
|
-
case "error":
|
|
779
|
-
console.log();
|
|
780
|
-
printError(event.error ?? event.content ?? "\uC54C \uC218 \uC5C6\uB294 \uC624\uB958");
|
|
781
|
-
break;
|
|
782
|
-
default:
|
|
783
|
-
if (event.content) {
|
|
784
|
-
if (!hasOutput) {
|
|
785
|
-
process.stdout.write(chalk7.green("\uC751\uB2F5: "));
|
|
786
|
-
hasOutput = true;
|
|
787
|
-
}
|
|
788
|
-
process.stdout.write(event.content);
|
|
789
|
-
}
|
|
790
|
-
}
|
|
791
|
-
},
|
|
792
|
-
() => {
|
|
793
|
-
if (hasOutput) {
|
|
794
|
-
console.log();
|
|
795
|
-
if (fullResponse.includes("```") || fullResponse.includes("**")) {
|
|
796
|
-
console.log(chalk7.gray("\u2500".repeat(40)));
|
|
797
|
-
console.log(renderMarkdown(fullResponse));
|
|
798
|
-
}
|
|
799
|
-
}
|
|
800
|
-
console.log();
|
|
801
|
-
console.log(chalk7.gray(`\uC138\uC158: ${interactionId}`));
|
|
802
|
-
},
|
|
803
|
-
(err) => {
|
|
804
|
-
console.log();
|
|
805
|
-
printError(`\uC2A4\uD2B8\uB9AC\uBC0D \uC624\uB958: ${err.message}`);
|
|
806
|
-
}
|
|
807
|
-
);
|
|
808
|
-
} catch (err) {
|
|
809
|
-
const msg = err?.response?.data?.detail ?? err.message;
|
|
810
|
-
printError(`\uC2E4\uD589 \uC2E4\uD328: ${msg}`);
|
|
811
|
-
process.exit(1);
|
|
812
|
-
}
|
|
813
|
-
}
|
|
814
|
-
|
|
815
|
-
// src/commands/workflow/history.ts
|
|
816
|
-
init_store();
|
|
817
|
-
import chalk8 from "chalk";
|
|
818
|
-
async function workflowHistory(workflowId, opts = {}) {
|
|
819
|
-
requireAuth();
|
|
820
|
-
const limit = opts.limit ?? 20;
|
|
821
|
-
try {
|
|
822
|
-
const logs = await getIOLogs(workflowId, limit);
|
|
823
|
-
if (!logs || logs.length === 0) {
|
|
824
|
-
console.log(chalk8.yellow("\n\uC2E4\uD589 \uC774\uB825\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.\n"));
|
|
825
|
-
return;
|
|
826
|
-
}
|
|
827
|
-
printHeader(`\uC2E4\uD589 \uC774\uB825 (\uCD5C\uADFC ${logs.length}\uAC74)`);
|
|
828
|
-
console.log();
|
|
829
|
-
for (const log of logs) {
|
|
830
|
-
console.log(
|
|
831
|
-
` ${chalk8.gray(formatDate(log.created_at))} ${chalk8.cyan(log.interaction_id)}`
|
|
832
|
-
);
|
|
833
|
-
console.log(` ${chalk8.white("\uC785\uB825:")} ${truncate(log.input_data, 60)}`);
|
|
834
|
-
console.log(
|
|
835
|
-
` ${chalk8.green("\uCD9C\uB825:")} ${truncate(log.output_data, 60)}`
|
|
836
|
-
);
|
|
837
|
-
if (log.execution_time) {
|
|
838
|
-
console.log(
|
|
839
|
-
` ${chalk8.gray("\uC2DC\uAC04:")} ${(log.execution_time / 1e3).toFixed(1)}s`
|
|
840
|
-
);
|
|
841
|
-
}
|
|
842
|
-
console.log();
|
|
843
|
-
}
|
|
844
|
-
} catch (err) {
|
|
845
|
-
const msg = err.message;
|
|
846
|
-
printError(`\uC774\uB825 \uC870\uD68C \uC2E4\uD328: ${msg}`);
|
|
847
|
-
process.exit(1);
|
|
848
|
-
}
|
|
849
|
-
}
|
|
850
|
-
|
|
851
|
-
// src/commands/workflow/index.ts
|
|
852
|
-
function registerWorkflowCommand(program2) {
|
|
853
|
-
const wf = program2.command("workflow").alias("wf").description("\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uAD00\uB9AC \uBC0F \uC2E4\uD589");
|
|
854
|
-
wf.command("list").alias("ls").description("\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uBAA9\uB85D \uC870\uD68C").option("-d, --detail", "\uC0C1\uC138 \uC815\uBCF4 \uD3EC\uD568").action((opts) => workflowList(opts));
|
|
855
|
-
wf.command("info <workflow-id>").description("\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uC0C1\uC138 \uC815\uBCF4").action((id) => workflowInfo(id));
|
|
856
|
-
wf.command("run <workflow-id> [input]").description("\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uC2E4\uD589").option("-i, --interactive", "\uC778\uD130\uB799\uD2F0\uBE0C \uBAA8\uB4DC (\uC785\uB825 \uD504\uB86C\uD504\uD2B8)").option("-l, --logs", "\uB514\uBC84\uADF8 \uB85C\uADF8 \uD45C\uC2DC").action((id, input, opts) => workflowRun(id, input, opts));
|
|
857
|
-
wf.command("history [workflow-id]").description("\uC2E4\uD589 \uC774\uB825 \uC870\uD68C").option("-n, --limit <number>", "\uC870\uD68C \uAC74\uC218", "20").action((id, opts) => workflowHistory(id, { limit: parseInt(opts.limit) }));
|
|
858
|
-
}
|
|
859
|
-
|
|
860
|
-
// src/commands/chat.ts
|
|
861
|
-
init_store();
|
|
862
|
-
import chalk9 from "chalk";
|
|
863
|
-
import { createInterface as createInterface2 } from "readline";
|
|
864
|
-
import { randomUUID as randomUUID2 } from "crypto";
|
|
865
|
-
var CHAT_BANNER = `
|
|
866
|
-
${chalk9.cyan("\u256D\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256E")}
|
|
867
|
-
${chalk9.cyan("\u2502")} ${chalk9.white.bold("XGEN")} ${chalk9.gray("\u2014 \uC6CC\uD06C\uD50C\uB85C\uC6B0 AI \uD130\uBBF8\uB110")} ${chalk9.cyan("\u2502")}
|
|
868
|
-
${chalk9.cyan("\u2502")} ${chalk9.gray("/help \uB3C4\uC6C0\uB9D0 /workflows \uC804\uD658 /exit")} ${chalk9.cyan("\u2502")}
|
|
869
|
-
${chalk9.cyan("\u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256F")}`;
|
|
870
|
-
function printHelp() {
|
|
871
|
-
console.log(`
|
|
872
|
-
${chalk9.bold("\uC2AC\uB798\uC2DC \uCEE4\uB9E8\uB4DC")}
|
|
873
|
-
${chalk9.cyan("/workflows")} \uC6CC\uD06C\uD50C\uB85C\uC6B0 \uBAA9\uB85D \uBCF4\uAE30 & \uC804\uD658
|
|
874
|
-
${chalk9.cyan("/switch")} \uC6CC\uD06C\uD50C\uB85C\uC6B0 \uBC88\uD638\uB85C \uC804\uD658 (\uC608: /switch 3)
|
|
875
|
-
${chalk9.cyan("/history")} \uD604\uC7AC \uC138\uC158 \uB300\uD654 \uC774\uB825
|
|
876
|
-
${chalk9.cyan("/clear")} \uD654\uBA74 \uC9C0\uC6B0\uAE30
|
|
877
|
-
${chalk9.cyan("/info")} \uD604\uC7AC \uC5F0\uACB0 \uC815\uBCF4
|
|
878
|
-
${chalk9.cyan("/help")} \uC774 \uB3C4\uC6C0\uB9D0
|
|
879
|
-
${chalk9.cyan("/exit")} \uC885\uB8CC (Ctrl+C\uB3C4 \uAC00\uB2A5)
|
|
880
|
-
`);
|
|
881
|
-
}
|
|
882
|
-
async function promptLine(rl, promptStr) {
|
|
883
|
-
return new Promise((resolve) => {
|
|
884
|
-
rl.question(promptStr, (answer) => resolve(answer));
|
|
885
|
-
});
|
|
886
|
-
}
|
|
887
|
-
async function chat(workflowId) {
|
|
888
|
-
const auth = requireAuth();
|
|
889
|
-
const server = getServer();
|
|
890
|
-
let workflows = [];
|
|
501
|
+
const server = getServer();
|
|
502
|
+
let workflows = [];
|
|
891
503
|
try {
|
|
892
504
|
workflows = await listWorkflows();
|
|
893
505
|
} catch {
|
|
@@ -1078,11 +690,26 @@ async function chat(workflowId) {
|
|
|
1078
690
|
function registerChatCommand(program2) {
|
|
1079
691
|
program2.command("chat [workflow-id]").description("\uC778\uD130\uB799\uD2F0\uBE0C \uB300\uD654 \uBAA8\uB4DC").action((workflowId) => chat(workflowId));
|
|
1080
692
|
}
|
|
693
|
+
var CHAT_BANNER;
|
|
694
|
+
var init_chat = __esm({
|
|
695
|
+
"src/commands/chat.ts"() {
|
|
696
|
+
"use strict";
|
|
697
|
+
init_store();
|
|
698
|
+
init_workflow();
|
|
699
|
+
init_sse();
|
|
700
|
+
init_format();
|
|
701
|
+
CHAT_BANNER = `
|
|
702
|
+
${chalk9.cyan("\u256D\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256E")}
|
|
703
|
+
${chalk9.cyan("\u2502")} ${chalk9.white.bold("XGEN")} ${chalk9.gray("\u2014 \uC6CC\uD06C\uD50C\uB85C\uC6B0 AI \uD130\uBBF8\uB110")} ${chalk9.cyan("\u2502")}
|
|
704
|
+
${chalk9.cyan("\u2502")} ${chalk9.gray("/help \uB3C4\uC6C0\uB9D0 /workflows \uC804\uD658 /exit")} ${chalk9.cyan("\u2502")}
|
|
705
|
+
${chalk9.cyan("\u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256F")}`;
|
|
706
|
+
}
|
|
707
|
+
});
|
|
1081
708
|
|
|
1082
709
|
// src/commands/provider.ts
|
|
1083
|
-
init_store();
|
|
1084
710
|
import chalk10 from "chalk";
|
|
1085
711
|
import { createInterface as createInterface3 } from "readline";
|
|
712
|
+
import OpenAI from "openai";
|
|
1086
713
|
function prompt2(question) {
|
|
1087
714
|
return new Promise((resolve) => {
|
|
1088
715
|
const rl = createInterface3({ input: process.stdin, output: process.stdout });
|
|
@@ -1092,56 +719,124 @@ function prompt2(question) {
|
|
|
1092
719
|
});
|
|
1093
720
|
});
|
|
1094
721
|
}
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
};
|
|
1102
|
-
|
|
1103
|
-
const
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
722
|
+
async function guidedProviderSetup() {
|
|
723
|
+
console.log(chalk10.cyan.bold("\n \u26A1 OPEN XGEN \u2014 \uD504\uB85C\uBC14\uC774\uB354 \uC124\uC815\n"));
|
|
724
|
+
console.log(chalk10.gray(" AI \uC5D0\uC774\uC804\uD2B8\uB97C \uC0AC\uC6A9\uD558\uB824\uBA74 \uD504\uB85C\uBC14\uC774\uB354\uB97C \uC124\uC815\uD558\uC138\uC694.\n"));
|
|
725
|
+
console.log(chalk10.bold(" \uD504\uB85C\uBC14\uC774\uB354 \uC120\uD0DD:\n"));
|
|
726
|
+
PRESETS.forEach((p, i) => {
|
|
727
|
+
console.log(` ${chalk10.cyan(`${i + 1})`)} ${p.label} ${chalk10.gray(`\u2014 ${p.defaultModel}`)}`);
|
|
728
|
+
});
|
|
729
|
+
console.log();
|
|
730
|
+
const choice = await prompt2(chalk10.white(" \uBC88\uD638 \uC120\uD0DD: "));
|
|
731
|
+
const idx = parseInt(choice) - 1;
|
|
732
|
+
if (isNaN(idx) || idx < 0 || idx >= PRESETS.length) {
|
|
733
|
+
printError("\uC798\uBABB\uB41C \uC120\uD0DD\uC785\uB2C8\uB2E4.");
|
|
734
|
+
return null;
|
|
735
|
+
}
|
|
736
|
+
const preset = PRESETS[idx];
|
|
737
|
+
console.log(chalk10.green(`
|
|
738
|
+
\u2713 ${preset.label} \uC120\uD0DD\uB428
|
|
739
|
+
`));
|
|
740
|
+
let apiKey = "";
|
|
741
|
+
if (preset.needsKey) {
|
|
742
|
+
console.log(chalk10.gray(` ${preset.keyHint}
|
|
743
|
+
`));
|
|
744
|
+
apiKey = await prompt2(chalk10.white(" API Key: "));
|
|
745
|
+
if (!apiKey) {
|
|
746
|
+
printError("API Key\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4.");
|
|
747
|
+
return null;
|
|
1113
748
|
}
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
if (
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
}
|
|
1122
|
-
let apiKey = "";
|
|
1123
|
-
if (type !== "ollama") {
|
|
1124
|
-
apiKey = await prompt2(chalk10.white("API Key: "));
|
|
1125
|
-
if (!apiKey) {
|
|
1126
|
-
printError("API Key\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4");
|
|
1127
|
-
process.exit(1);
|
|
1128
|
-
}
|
|
749
|
+
}
|
|
750
|
+
let baseUrl = preset.baseUrl;
|
|
751
|
+
if (preset.type === "custom") {
|
|
752
|
+
const url = await prompt2(chalk10.white(" Base URL: "));
|
|
753
|
+
if (!url) {
|
|
754
|
+
printError("Base URL\uC774 \uD544\uC694\uD569\uB2C8\uB2E4.");
|
|
755
|
+
return null;
|
|
1129
756
|
}
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
757
|
+
baseUrl = url;
|
|
758
|
+
} else if (preset.type === "ollama") {
|
|
759
|
+
const url = await prompt2(chalk10.white(` Base URL [${preset.baseUrl}]: `));
|
|
760
|
+
if (url) baseUrl = url;
|
|
761
|
+
}
|
|
762
|
+
let model = preset.defaultModel;
|
|
763
|
+
if (preset.models.length > 0) {
|
|
764
|
+
console.log(chalk10.bold("\n \uBAA8\uB378 \uC120\uD0DD:\n"));
|
|
765
|
+
preset.models.forEach((m, i) => {
|
|
766
|
+
const isDefault = m === preset.defaultModel ? chalk10.gray(" (\uAE30\uBCF8)") : "";
|
|
767
|
+
console.log(` ${chalk10.cyan(`${i + 1})`)} ${m}${isDefault}`);
|
|
768
|
+
});
|
|
769
|
+
console.log(` ${chalk10.cyan(`${preset.models.length + 1})`)} \uC9C1\uC811 \uC785\uB825`);
|
|
1133
770
|
console.log();
|
|
1134
|
-
|
|
771
|
+
const defaultIdx = preset.models.indexOf(preset.defaultModel);
|
|
772
|
+
const mc = await prompt2(chalk10.white(` \uBC88\uD638 \uC120\uD0DD [${defaultIdx + 1}]: `));
|
|
773
|
+
if (!mc) {
|
|
774
|
+
model = preset.defaultModel;
|
|
775
|
+
} else {
|
|
776
|
+
const mi = parseInt(mc) - 1;
|
|
777
|
+
if (!isNaN(mi) && mi >= 0 && mi < preset.models.length) {
|
|
778
|
+
model = preset.models[mi];
|
|
779
|
+
} else if (parseInt(mc) === preset.models.length + 1) {
|
|
780
|
+
model = await prompt2(chalk10.white(" \uBAA8\uB378 \uC774\uB984: ")) || preset.defaultModel;
|
|
781
|
+
} else {
|
|
782
|
+
model = preset.defaultModel;
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
} else {
|
|
786
|
+
model = await prompt2(chalk10.white(` \uBAA8\uB378 \uC774\uB984 [${preset.defaultModel}]: `)) || preset.defaultModel;
|
|
787
|
+
}
|
|
788
|
+
console.log(chalk10.green(`
|
|
789
|
+
\u2713 \uBAA8\uB378: ${model}`));
|
|
790
|
+
console.log(chalk10.gray("\n \uC5F0\uACB0 \uD14C\uC2A4\uD2B8 \uC911..."));
|
|
791
|
+
const provider = {
|
|
792
|
+
id: preset.type,
|
|
793
|
+
name: preset.label,
|
|
794
|
+
type: preset.type,
|
|
795
|
+
baseUrl,
|
|
796
|
+
apiKey,
|
|
797
|
+
model
|
|
798
|
+
};
|
|
799
|
+
try {
|
|
800
|
+
const client2 = new OpenAI({
|
|
801
|
+
apiKey: apiKey || "ollama",
|
|
802
|
+
baseURL: baseUrl
|
|
803
|
+
});
|
|
804
|
+
const res = await client2.chat.completions.create({
|
|
805
|
+
model,
|
|
806
|
+
messages: [{ role: "user", content: "Hi" }],
|
|
807
|
+
max_tokens: 5
|
|
808
|
+
});
|
|
809
|
+
if (res.choices[0]) {
|
|
810
|
+
console.log(chalk10.green(" \u2713 \uC5F0\uACB0 \uC131\uACF5!\n"));
|
|
811
|
+
}
|
|
812
|
+
} catch (err) {
|
|
813
|
+
console.log(chalk10.yellow(` \u26A0 \uC5F0\uACB0 \uD14C\uC2A4\uD2B8 \uC2E4\uD328: ${err.message}`));
|
|
814
|
+
console.log(chalk10.gray(" \uC124\uC815\uC740 \uC800\uC7A5\uB429\uB2C8\uB2E4. \uB098\uC911\uC5D0 \uB2E4\uC2DC \uC2DC\uB3C4\uD558\uC138\uC694.\n"));
|
|
815
|
+
}
|
|
816
|
+
addProvider(provider);
|
|
817
|
+
console.log(chalk10.green.bold(` \u2713 ${preset.label} (${model}) \uC124\uC815 \uC644\uB8CC!
|
|
818
|
+
`));
|
|
819
|
+
console.log(chalk10.gray(` \uC774\uC81C ${chalk10.cyan("xgen agent")} \uB610\uB294 ${chalk10.cyan("xgen")} \uC73C\uB85C \uC2DC\uC791\uD558\uC138\uC694.
|
|
820
|
+
`));
|
|
821
|
+
return provider;
|
|
822
|
+
}
|
|
823
|
+
function registerProviderCommand(program2) {
|
|
824
|
+
const prov = program2.command("provider").description("AI \uD504\uB85C\uBC14\uC774\uB354 \uAD00\uB9AC");
|
|
825
|
+
prov.command("add").description("\uD504\uB85C\uBC14\uC774\uB354 \uCD94\uAC00 (\uAC00\uC774\uB4DC \uC124\uC815)").action(async () => {
|
|
826
|
+
await guidedProviderSetup();
|
|
1135
827
|
});
|
|
1136
828
|
prov.command("list").alias("ls").description("\uD504\uB85C\uBC14\uC774\uB354 \uBAA9\uB85D").action(() => {
|
|
1137
829
|
const providers = getProviders();
|
|
1138
830
|
const defaultP = getDefaultProvider();
|
|
1139
831
|
if (providers.length === 0) {
|
|
1140
|
-
console.log(chalk10.yellow("\n\uD504\uB85C\uBC14\uC774\uB354\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.
|
|
832
|
+
console.log(chalk10.yellow("\n \uD504\uB85C\uBC14\uC774\uB354\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4."));
|
|
833
|
+
console.log(` ${chalk10.cyan("xgen provider add")} \uB85C \uCD94\uAC00\uD558\uC138\uC694.
|
|
834
|
+
`);
|
|
1141
835
|
return;
|
|
1142
836
|
}
|
|
1143
|
-
|
|
1144
|
-
|
|
837
|
+
console.log(chalk10.cyan.bold(`
|
|
838
|
+
\uD504\uB85C\uBC14\uC774\uB354 (${providers.length}\uAC1C)
|
|
839
|
+
`));
|
|
1145
840
|
printTable(
|
|
1146
841
|
["", "ID", "\uC774\uB984", "\uD0C0\uC785", "\uBAA8\uB378"],
|
|
1147
842
|
providers.map((p) => [
|
|
@@ -1169,14 +864,62 @@ function registerProviderCommand(program2) {
|
|
|
1169
864
|
}
|
|
1170
865
|
});
|
|
1171
866
|
}
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
867
|
+
var PRESETS;
|
|
868
|
+
var init_provider = __esm({
|
|
869
|
+
"src/commands/provider.ts"() {
|
|
870
|
+
"use strict";
|
|
871
|
+
init_store();
|
|
872
|
+
init_format();
|
|
873
|
+
PRESETS = [
|
|
874
|
+
{
|
|
875
|
+
label: "OpenAI",
|
|
876
|
+
type: "openai",
|
|
877
|
+
defaultModel: "gpt-4o-mini",
|
|
878
|
+
models: ["gpt-4o", "gpt-4o-mini", "gpt-4.1", "gpt-4.1-mini", "o3-mini"],
|
|
879
|
+
needsKey: true,
|
|
880
|
+
keyHint: "https://platform.openai.com/api-keys \uC5D0\uC11C \uBC1C\uAE09"
|
|
881
|
+
},
|
|
882
|
+
{
|
|
883
|
+
label: "Google Gemini",
|
|
884
|
+
type: "gemini",
|
|
885
|
+
baseUrl: "https://generativelanguage.googleapis.com/v1beta/openai",
|
|
886
|
+
defaultModel: "gemini-2.0-flash",
|
|
887
|
+
models: ["gemini-2.0-flash", "gemini-2.5-pro-preview-06-05", "gemini-2.5-flash-preview-05-20"],
|
|
888
|
+
needsKey: true,
|
|
889
|
+
keyHint: "https://aistudio.google.com/apikey \uC5D0\uC11C \uBC1C\uAE09"
|
|
890
|
+
},
|
|
891
|
+
{
|
|
892
|
+
label: "Ollama (\uB85C\uCEEC)",
|
|
893
|
+
type: "ollama",
|
|
894
|
+
baseUrl: "http://localhost:11434/v1",
|
|
895
|
+
defaultModel: "llama3.1",
|
|
896
|
+
models: ["llama3.1", "llama3.2", "codellama", "mistral", "qwen2.5-coder"],
|
|
897
|
+
needsKey: false,
|
|
898
|
+
keyHint: "https://ollama.ai \uC5D0\uC11C \uC124\uCE58"
|
|
899
|
+
},
|
|
900
|
+
{
|
|
901
|
+
label: "Anthropic (Claude)",
|
|
902
|
+
type: "anthropic",
|
|
903
|
+
baseUrl: "https://api.anthropic.com/v1",
|
|
904
|
+
defaultModel: "claude-sonnet-4-20250514",
|
|
905
|
+
models: ["claude-sonnet-4-20250514", "claude-opus-4-20250514", "claude-haiku-4-5-20251001"],
|
|
906
|
+
needsKey: true,
|
|
907
|
+
keyHint: "https://console.anthropic.com/settings/keys \uC5D0\uC11C \uBC1C\uAE09"
|
|
908
|
+
},
|
|
909
|
+
{
|
|
910
|
+
label: "Custom (OpenAI \uD638\uD658 \uC11C\uBC84)",
|
|
911
|
+
type: "custom",
|
|
912
|
+
defaultModel: "gpt-4o-mini",
|
|
913
|
+
models: [],
|
|
914
|
+
needsKey: true,
|
|
915
|
+
keyHint: "\uC11C\uBC84\uC5D0\uC11C \uBC1C\uAE09\uBC1B\uC740 API Key"
|
|
916
|
+
}
|
|
917
|
+
];
|
|
918
|
+
}
|
|
919
|
+
});
|
|
1177
920
|
|
|
1178
921
|
// src/agent/llm.ts
|
|
1179
|
-
import
|
|
922
|
+
import OpenAI2 from "openai";
|
|
1180
923
|
function createLLMClient(provider) {
|
|
1181
924
|
const opts = {
|
|
1182
925
|
apiKey: provider.apiKey || "ollama"
|
|
@@ -1184,7 +927,7 @@ function createLLMClient(provider) {
|
|
|
1184
927
|
if (provider.baseUrl) {
|
|
1185
928
|
opts.baseURL = provider.baseUrl;
|
|
1186
929
|
}
|
|
1187
|
-
return new
|
|
930
|
+
return new OpenAI2(opts);
|
|
1188
931
|
}
|
|
1189
932
|
async function streamChat(client2, model, messages, tools2, onDelta) {
|
|
1190
933
|
const params = {
|
|
@@ -1223,6 +966,11 @@ async function streamChat(client2, model, messages, tools2, onDelta) {
|
|
|
1223
966
|
toolCalls: [...toolCallMap.values()]
|
|
1224
967
|
};
|
|
1225
968
|
}
|
|
969
|
+
var init_llm = __esm({
|
|
970
|
+
"src/agent/llm.ts"() {
|
|
971
|
+
"use strict";
|
|
972
|
+
}
|
|
973
|
+
});
|
|
1226
974
|
|
|
1227
975
|
// src/agent/tools/file-read.ts
|
|
1228
976
|
var file_read_exports = {};
|
|
@@ -1231,22 +979,6 @@ __export(file_read_exports, {
|
|
|
1231
979
|
execute: () => execute
|
|
1232
980
|
});
|
|
1233
981
|
import { readFileSync as readFileSync2 } from "fs";
|
|
1234
|
-
var definition = {
|
|
1235
|
-
type: "function",
|
|
1236
|
-
function: {
|
|
1237
|
-
name: "file_read",
|
|
1238
|
-
description: "\uD30C\uC77C \uB0B4\uC6A9\uC744 \uC77D\uC2B5\uB2C8\uB2E4. \uC904 \uBC88\uD638\uAC00 \uD3EC\uD568\uB429\uB2C8\uB2E4.",
|
|
1239
|
-
parameters: {
|
|
1240
|
-
type: "object",
|
|
1241
|
-
properties: {
|
|
1242
|
-
path: { type: "string", description: "\uD30C\uC77C \uACBD\uB85C" },
|
|
1243
|
-
start_line: { type: "number", description: "\uC2DC\uC791 \uC904 \uBC88\uD638 (\uC120\uD0DD)" },
|
|
1244
|
-
end_line: { type: "number", description: "\uB05D \uC904 \uBC88\uD638 (\uC120\uD0DD)" }
|
|
1245
|
-
},
|
|
1246
|
-
required: ["path"]
|
|
1247
|
-
}
|
|
1248
|
-
}
|
|
1249
|
-
};
|
|
1250
982
|
async function execute(args) {
|
|
1251
983
|
const path = args.path;
|
|
1252
984
|
const startLine = args.start_line || 1;
|
|
@@ -1260,8 +992,30 @@ async function execute(args) {
|
|
|
1260
992
|
return `Error: ${err.message}`;
|
|
1261
993
|
}
|
|
1262
994
|
}
|
|
1263
|
-
|
|
1264
|
-
|
|
995
|
+
var definition;
|
|
996
|
+
var init_file_read = __esm({
|
|
997
|
+
"src/agent/tools/file-read.ts"() {
|
|
998
|
+
"use strict";
|
|
999
|
+
definition = {
|
|
1000
|
+
type: "function",
|
|
1001
|
+
function: {
|
|
1002
|
+
name: "file_read",
|
|
1003
|
+
description: "\uD30C\uC77C \uB0B4\uC6A9\uC744 \uC77D\uC2B5\uB2C8\uB2E4. \uC904 \uBC88\uD638\uAC00 \uD3EC\uD568\uB429\uB2C8\uB2E4.",
|
|
1004
|
+
parameters: {
|
|
1005
|
+
type: "object",
|
|
1006
|
+
properties: {
|
|
1007
|
+
path: { type: "string", description: "\uD30C\uC77C \uACBD\uB85C" },
|
|
1008
|
+
start_line: { type: "number", description: "\uC2DC\uC791 \uC904 \uBC88\uD638 (\uC120\uD0DD)" },
|
|
1009
|
+
end_line: { type: "number", description: "\uB05D \uC904 \uBC88\uD638 (\uC120\uD0DD)" }
|
|
1010
|
+
},
|
|
1011
|
+
required: ["path"]
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
};
|
|
1015
|
+
}
|
|
1016
|
+
});
|
|
1017
|
+
|
|
1018
|
+
// src/agent/tools/file-write.ts
|
|
1265
1019
|
var file_write_exports = {};
|
|
1266
1020
|
__export(file_write_exports, {
|
|
1267
1021
|
definition: () => definition2,
|
|
@@ -1269,21 +1023,6 @@ __export(file_write_exports, {
|
|
|
1269
1023
|
});
|
|
1270
1024
|
import { writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "fs";
|
|
1271
1025
|
import { dirname } from "path";
|
|
1272
|
-
var definition2 = {
|
|
1273
|
-
type: "function",
|
|
1274
|
-
function: {
|
|
1275
|
-
name: "file_write",
|
|
1276
|
-
description: "\uD30C\uC77C\uC744 \uC0DD\uC131\uD558\uAC70\uB098 \uB36E\uC5B4\uC501\uB2C8\uB2E4.",
|
|
1277
|
-
parameters: {
|
|
1278
|
-
type: "object",
|
|
1279
|
-
properties: {
|
|
1280
|
-
path: { type: "string", description: "\uD30C\uC77C \uACBD\uB85C" },
|
|
1281
|
-
content: { type: "string", description: "\uD30C\uC77C \uB0B4\uC6A9" }
|
|
1282
|
-
},
|
|
1283
|
-
required: ["path", "content"]
|
|
1284
|
-
}
|
|
1285
|
-
}
|
|
1286
|
-
};
|
|
1287
1026
|
async function execute2(args) {
|
|
1288
1027
|
const path = args.path;
|
|
1289
1028
|
const content = args.content;
|
|
@@ -1295,6 +1034,27 @@ async function execute2(args) {
|
|
|
1295
1034
|
return `Error: ${err.message}`;
|
|
1296
1035
|
}
|
|
1297
1036
|
}
|
|
1037
|
+
var definition2;
|
|
1038
|
+
var init_file_write = __esm({
|
|
1039
|
+
"src/agent/tools/file-write.ts"() {
|
|
1040
|
+
"use strict";
|
|
1041
|
+
definition2 = {
|
|
1042
|
+
type: "function",
|
|
1043
|
+
function: {
|
|
1044
|
+
name: "file_write",
|
|
1045
|
+
description: "\uD30C\uC77C\uC744 \uC0DD\uC131\uD558\uAC70\uB098 \uB36E\uC5B4\uC501\uB2C8\uB2E4.",
|
|
1046
|
+
parameters: {
|
|
1047
|
+
type: "object",
|
|
1048
|
+
properties: {
|
|
1049
|
+
path: { type: "string", description: "\uD30C\uC77C \uACBD\uB85C" },
|
|
1050
|
+
content: { type: "string", description: "\uD30C\uC77C \uB0B4\uC6A9" }
|
|
1051
|
+
},
|
|
1052
|
+
required: ["path", "content"]
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
1055
|
+
};
|
|
1056
|
+
}
|
|
1057
|
+
});
|
|
1298
1058
|
|
|
1299
1059
|
// src/agent/tools/file-edit.ts
|
|
1300
1060
|
var file_edit_exports = {};
|
|
@@ -1303,22 +1063,6 @@ __export(file_edit_exports, {
|
|
|
1303
1063
|
execute: () => execute3
|
|
1304
1064
|
});
|
|
1305
1065
|
import { readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
|
|
1306
|
-
var definition3 = {
|
|
1307
|
-
type: "function",
|
|
1308
|
-
function: {
|
|
1309
|
-
name: "file_edit",
|
|
1310
|
-
description: "\uD30C\uC77C\uC5D0\uC11C \uD2B9\uC815 \uD14D\uC2A4\uD2B8\uB97C \uCC3E\uC544 \uAD50\uCCB4\uD569\uB2C8\uB2E4.",
|
|
1311
|
-
parameters: {
|
|
1312
|
-
type: "object",
|
|
1313
|
-
properties: {
|
|
1314
|
-
path: { type: "string", description: "\uD30C\uC77C \uACBD\uB85C" },
|
|
1315
|
-
old_text: { type: "string", description: "\uAD50\uCCB4\uD560 \uAE30\uC874 \uD14D\uC2A4\uD2B8" },
|
|
1316
|
-
new_text: { type: "string", description: "\uC0C8 \uD14D\uC2A4\uD2B8" }
|
|
1317
|
-
},
|
|
1318
|
-
required: ["path", "old_text", "new_text"]
|
|
1319
|
-
}
|
|
1320
|
-
}
|
|
1321
|
-
};
|
|
1322
1066
|
async function execute3(args) {
|
|
1323
1067
|
const path = args.path;
|
|
1324
1068
|
const oldText = args.old_text;
|
|
@@ -1335,6 +1079,28 @@ async function execute3(args) {
|
|
|
1335
1079
|
return `Error: ${err.message}`;
|
|
1336
1080
|
}
|
|
1337
1081
|
}
|
|
1082
|
+
var definition3;
|
|
1083
|
+
var init_file_edit = __esm({
|
|
1084
|
+
"src/agent/tools/file-edit.ts"() {
|
|
1085
|
+
"use strict";
|
|
1086
|
+
definition3 = {
|
|
1087
|
+
type: "function",
|
|
1088
|
+
function: {
|
|
1089
|
+
name: "file_edit",
|
|
1090
|
+
description: "\uD30C\uC77C\uC5D0\uC11C \uD2B9\uC815 \uD14D\uC2A4\uD2B8\uB97C \uCC3E\uC544 \uAD50\uCCB4\uD569\uB2C8\uB2E4.",
|
|
1091
|
+
parameters: {
|
|
1092
|
+
type: "object",
|
|
1093
|
+
properties: {
|
|
1094
|
+
path: { type: "string", description: "\uD30C\uC77C \uACBD\uB85C" },
|
|
1095
|
+
old_text: { type: "string", description: "\uAD50\uCCB4\uD560 \uAE30\uC874 \uD14D\uC2A4\uD2B8" },
|
|
1096
|
+
new_text: { type: "string", description: "\uC0C8 \uD14D\uC2A4\uD2B8" }
|
|
1097
|
+
},
|
|
1098
|
+
required: ["path", "old_text", "new_text"]
|
|
1099
|
+
}
|
|
1100
|
+
}
|
|
1101
|
+
};
|
|
1102
|
+
}
|
|
1103
|
+
});
|
|
1338
1104
|
|
|
1339
1105
|
// src/agent/tools/bash.ts
|
|
1340
1106
|
var bash_exports = {};
|
|
@@ -1343,20 +1109,6 @@ __export(bash_exports, {
|
|
|
1343
1109
|
execute: () => execute4
|
|
1344
1110
|
});
|
|
1345
1111
|
import { execSync } from "child_process";
|
|
1346
|
-
var definition4 = {
|
|
1347
|
-
type: "function",
|
|
1348
|
-
function: {
|
|
1349
|
-
name: "bash",
|
|
1350
|
-
description: "\uC178 \uBA85\uB839\uC5B4\uB97C \uC2E4\uD589\uD569\uB2C8\uB2E4. stdout + stderr\uB97C \uBC18\uD658\uD569\uB2C8\uB2E4.",
|
|
1351
|
-
parameters: {
|
|
1352
|
-
type: "object",
|
|
1353
|
-
properties: {
|
|
1354
|
-
command: { type: "string", description: "\uC2E4\uD589\uD560 \uBA85\uB839\uC5B4" }
|
|
1355
|
-
},
|
|
1356
|
-
required: ["command"]
|
|
1357
|
-
}
|
|
1358
|
-
}
|
|
1359
|
-
};
|
|
1360
1112
|
async function execute4(args) {
|
|
1361
1113
|
const command = args.command;
|
|
1362
1114
|
try {
|
|
@@ -1372,6 +1124,26 @@ async function execute4(args) {
|
|
|
1372
1124
|
return (e.stdout || "") + (e.stderr || "") || `Error: ${e.message}`;
|
|
1373
1125
|
}
|
|
1374
1126
|
}
|
|
1127
|
+
var definition4;
|
|
1128
|
+
var init_bash = __esm({
|
|
1129
|
+
"src/agent/tools/bash.ts"() {
|
|
1130
|
+
"use strict";
|
|
1131
|
+
definition4 = {
|
|
1132
|
+
type: "function",
|
|
1133
|
+
function: {
|
|
1134
|
+
name: "bash",
|
|
1135
|
+
description: "\uC178 \uBA85\uB839\uC5B4\uB97C \uC2E4\uD589\uD569\uB2C8\uB2E4. stdout + stderr\uB97C \uBC18\uD658\uD569\uB2C8\uB2E4.",
|
|
1136
|
+
parameters: {
|
|
1137
|
+
type: "object",
|
|
1138
|
+
properties: {
|
|
1139
|
+
command: { type: "string", description: "\uC2E4\uD589\uD560 \uBA85\uB839\uC5B4" }
|
|
1140
|
+
},
|
|
1141
|
+
required: ["command"]
|
|
1142
|
+
}
|
|
1143
|
+
}
|
|
1144
|
+
};
|
|
1145
|
+
}
|
|
1146
|
+
});
|
|
1375
1147
|
|
|
1376
1148
|
// src/agent/tools/grep.ts
|
|
1377
1149
|
var grep_exports = {};
|
|
@@ -1380,22 +1152,6 @@ __export(grep_exports, {
|
|
|
1380
1152
|
execute: () => execute5
|
|
1381
1153
|
});
|
|
1382
1154
|
import { execSync as execSync2 } from "child_process";
|
|
1383
|
-
var definition5 = {
|
|
1384
|
-
type: "function",
|
|
1385
|
-
function: {
|
|
1386
|
-
name: "grep",
|
|
1387
|
-
description: "\uD30C\uC77C\uC5D0\uC11C \uD328\uD134\uC744 \uAC80\uC0C9\uD569\uB2C8\uB2E4 (\uC7AC\uADC0, \uC904 \uBC88\uD638 \uD3EC\uD568).",
|
|
1388
|
-
parameters: {
|
|
1389
|
-
type: "object",
|
|
1390
|
-
properties: {
|
|
1391
|
-
pattern: { type: "string", description: "\uAC80\uC0C9 \uD328\uD134 (\uC815\uADDC\uC2DD)" },
|
|
1392
|
-
path: { type: "string", description: "\uAC80\uC0C9 \uB514\uB809\uD1A0\uB9AC \uB610\uB294 \uD30C\uC77C (\uAE30\uBCF8: .)" },
|
|
1393
|
-
glob: { type: "string", description: "\uD30C\uC77C \uD544\uD130 (\uC608: *.ts)" }
|
|
1394
|
-
},
|
|
1395
|
-
required: ["pattern"]
|
|
1396
|
-
}
|
|
1397
|
-
}
|
|
1398
|
-
};
|
|
1399
1155
|
async function execute5(args) {
|
|
1400
1156
|
const pattern = args.pattern;
|
|
1401
1157
|
const path = args.path || ".";
|
|
@@ -1415,6 +1171,28 @@ async function execute5(args) {
|
|
|
1415
1171
|
return "\uC77C\uCE58\uD558\uB294 \uACB0\uACFC \uC5C6\uC74C";
|
|
1416
1172
|
}
|
|
1417
1173
|
}
|
|
1174
|
+
var definition5;
|
|
1175
|
+
var init_grep = __esm({
|
|
1176
|
+
"src/agent/tools/grep.ts"() {
|
|
1177
|
+
"use strict";
|
|
1178
|
+
definition5 = {
|
|
1179
|
+
type: "function",
|
|
1180
|
+
function: {
|
|
1181
|
+
name: "grep",
|
|
1182
|
+
description: "\uD30C\uC77C\uC5D0\uC11C \uD328\uD134\uC744 \uAC80\uC0C9\uD569\uB2C8\uB2E4 (\uC7AC\uADC0, \uC904 \uBC88\uD638 \uD3EC\uD568).",
|
|
1183
|
+
parameters: {
|
|
1184
|
+
type: "object",
|
|
1185
|
+
properties: {
|
|
1186
|
+
pattern: { type: "string", description: "\uAC80\uC0C9 \uD328\uD134 (\uC815\uADDC\uC2DD)" },
|
|
1187
|
+
path: { type: "string", description: "\uAC80\uC0C9 \uB514\uB809\uD1A0\uB9AC \uB610\uB294 \uD30C\uC77C (\uAE30\uBCF8: .)" },
|
|
1188
|
+
glob: { type: "string", description: "\uD30C\uC77C \uD544\uD130 (\uC608: *.ts)" }
|
|
1189
|
+
},
|
|
1190
|
+
required: ["pattern"]
|
|
1191
|
+
}
|
|
1192
|
+
}
|
|
1193
|
+
};
|
|
1194
|
+
}
|
|
1195
|
+
});
|
|
1418
1196
|
|
|
1419
1197
|
// src/agent/tools/list-files.ts
|
|
1420
1198
|
var list_files_exports = {};
|
|
@@ -1423,20 +1201,6 @@ __export(list_files_exports, {
|
|
|
1423
1201
|
execute: () => execute6
|
|
1424
1202
|
});
|
|
1425
1203
|
import { execSync as execSync3 } from "child_process";
|
|
1426
|
-
var definition6 = {
|
|
1427
|
-
type: "function",
|
|
1428
|
-
function: {
|
|
1429
|
-
name: "list_files",
|
|
1430
|
-
description: "\uB514\uB809\uD1A0\uB9AC\uC758 \uD30C\uC77C/\uD3F4\uB354 \uBAA9\uB85D\uC744 \uBC18\uD658\uD569\uB2C8\uB2E4. glob \uD328\uD134 \uC9C0\uC6D0.",
|
|
1431
|
-
parameters: {
|
|
1432
|
-
type: "object",
|
|
1433
|
-
properties: {
|
|
1434
|
-
path: { type: "string", description: "\uB514\uB809\uD1A0\uB9AC \uACBD\uB85C (\uAE30\uBCF8: .)" },
|
|
1435
|
-
pattern: { type: "string", description: "glob \uD328\uD134 (\uC608: **/*.ts)" }
|
|
1436
|
-
}
|
|
1437
|
-
}
|
|
1438
|
-
}
|
|
1439
|
-
};
|
|
1440
1204
|
async function execute6(args) {
|
|
1441
1205
|
const path = args.path || ".";
|
|
1442
1206
|
const pattern = args.pattern;
|
|
@@ -1457,6 +1221,26 @@ async function execute6(args) {
|
|
|
1457
1221
|
return `Error: ${err.message}`;
|
|
1458
1222
|
}
|
|
1459
1223
|
}
|
|
1224
|
+
var definition6;
|
|
1225
|
+
var init_list_files = __esm({
|
|
1226
|
+
"src/agent/tools/list-files.ts"() {
|
|
1227
|
+
"use strict";
|
|
1228
|
+
definition6 = {
|
|
1229
|
+
type: "function",
|
|
1230
|
+
function: {
|
|
1231
|
+
name: "list_files",
|
|
1232
|
+
description: "\uB514\uB809\uD1A0\uB9AC\uC758 \uD30C\uC77C/\uD3F4\uB354 \uBAA9\uB85D\uC744 \uBC18\uD658\uD569\uB2C8\uB2E4. glob \uD328\uD134 \uC9C0\uC6D0.",
|
|
1233
|
+
parameters: {
|
|
1234
|
+
type: "object",
|
|
1235
|
+
properties: {
|
|
1236
|
+
path: { type: "string", description: "\uB514\uB809\uD1A0\uB9AC \uACBD\uB85C (\uAE30\uBCF8: .)" },
|
|
1237
|
+
pattern: { type: "string", description: "glob \uD328\uD134 (\uC608: **/*.ts)" }
|
|
1238
|
+
}
|
|
1239
|
+
}
|
|
1240
|
+
}
|
|
1241
|
+
};
|
|
1242
|
+
}
|
|
1243
|
+
});
|
|
1460
1244
|
|
|
1461
1245
|
// src/agent/tools/sandbox.ts
|
|
1462
1246
|
var sandbox_exports = {};
|
|
@@ -1468,37 +1252,12 @@ import { execSync as execSync4 } from "child_process";
|
|
|
1468
1252
|
import { mkdirSync as mkdirSync3, writeFileSync as writeFileSync4, existsSync as existsSync2, rmSync } from "fs";
|
|
1469
1253
|
import { join as join2 } from "path";
|
|
1470
1254
|
import { tmpdir } from "os";
|
|
1471
|
-
var SANDBOX_DIR = join2(tmpdir(), "xgen-sandbox");
|
|
1472
1255
|
function ensureSandbox() {
|
|
1473
1256
|
if (!existsSync2(SANDBOX_DIR)) {
|
|
1474
1257
|
mkdirSync3(SANDBOX_DIR, { recursive: true });
|
|
1475
1258
|
}
|
|
1476
1259
|
return SANDBOX_DIR;
|
|
1477
1260
|
}
|
|
1478
|
-
var definition7 = {
|
|
1479
|
-
type: "function",
|
|
1480
|
-
function: {
|
|
1481
|
-
name: "sandbox_run",
|
|
1482
|
-
description: "\uACA9\uB9AC\uB41C \uC0CC\uB4DC\uBC15\uC2A4\uC5D0\uC11C \uCF54\uB4DC\uB97C \uC2E4\uD589\uD569\uB2C8\uB2E4. Node.js \uB610\uB294 Python \uCF54\uB4DC\uB97C \uC548\uC804\uD558\uAC8C \uC2E4\uD589\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4. npm \uD328\uD0A4\uC9C0 \uC124\uCE58\uB3C4 \uAC00\uB2A5\uD569\uB2C8\uB2E4.",
|
|
1483
|
-
parameters: {
|
|
1484
|
-
type: "object",
|
|
1485
|
-
properties: {
|
|
1486
|
-
language: {
|
|
1487
|
-
type: "string",
|
|
1488
|
-
enum: ["javascript", "typescript", "python"],
|
|
1489
|
-
description: "\uC2E4\uD589\uD560 \uC5B8\uC5B4"
|
|
1490
|
-
},
|
|
1491
|
-
code: { type: "string", description: "\uC2E4\uD589\uD560 \uCF54\uB4DC" },
|
|
1492
|
-
packages: {
|
|
1493
|
-
type: "array",
|
|
1494
|
-
items: { type: "string" },
|
|
1495
|
-
description: "\uC124\uCE58\uD560 \uD328\uD0A4\uC9C0 (npm \uB610\uB294 pip)"
|
|
1496
|
-
}
|
|
1497
|
-
},
|
|
1498
|
-
required: ["language", "code"]
|
|
1499
|
-
}
|
|
1500
|
-
}
|
|
1501
|
-
};
|
|
1502
1261
|
async function execute7(args) {
|
|
1503
1262
|
const language = args.language;
|
|
1504
1263
|
const code = args.code;
|
|
@@ -1561,13 +1320,39 @@ async function execute7(args) {
|
|
|
1561
1320
|
}
|
|
1562
1321
|
}
|
|
1563
1322
|
}
|
|
1323
|
+
var SANDBOX_DIR, definition7;
|
|
1324
|
+
var init_sandbox = __esm({
|
|
1325
|
+
"src/agent/tools/sandbox.ts"() {
|
|
1326
|
+
"use strict";
|
|
1327
|
+
SANDBOX_DIR = join2(tmpdir(), "xgen-sandbox");
|
|
1328
|
+
definition7 = {
|
|
1329
|
+
type: "function",
|
|
1330
|
+
function: {
|
|
1331
|
+
name: "sandbox_run",
|
|
1332
|
+
description: "\uACA9\uB9AC\uB41C \uC0CC\uB4DC\uBC15\uC2A4\uC5D0\uC11C \uCF54\uB4DC\uB97C \uC2E4\uD589\uD569\uB2C8\uB2E4. Node.js \uB610\uB294 Python \uCF54\uB4DC\uB97C \uC548\uC804\uD558\uAC8C \uC2E4\uD589\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4. npm \uD328\uD0A4\uC9C0 \uC124\uCE58\uB3C4 \uAC00\uB2A5\uD569\uB2C8\uB2E4.",
|
|
1333
|
+
parameters: {
|
|
1334
|
+
type: "object",
|
|
1335
|
+
properties: {
|
|
1336
|
+
language: {
|
|
1337
|
+
type: "string",
|
|
1338
|
+
enum: ["javascript", "typescript", "python"],
|
|
1339
|
+
description: "\uC2E4\uD589\uD560 \uC5B8\uC5B4"
|
|
1340
|
+
},
|
|
1341
|
+
code: { type: "string", description: "\uC2E4\uD589\uD560 \uCF54\uB4DC" },
|
|
1342
|
+
packages: {
|
|
1343
|
+
type: "array",
|
|
1344
|
+
items: { type: "string" },
|
|
1345
|
+
description: "\uC124\uCE58\uD560 \uD328\uD0A4\uC9C0 (npm \uB610\uB294 pip)"
|
|
1346
|
+
}
|
|
1347
|
+
},
|
|
1348
|
+
required: ["language", "code"]
|
|
1349
|
+
}
|
|
1350
|
+
}
|
|
1351
|
+
};
|
|
1352
|
+
}
|
|
1353
|
+
});
|
|
1564
1354
|
|
|
1565
1355
|
// src/agent/tools/index.ts
|
|
1566
|
-
var tools = [file_read_exports, file_write_exports, file_edit_exports, bash_exports, grep_exports, list_files_exports, sandbox_exports];
|
|
1567
|
-
var toolMap = /* @__PURE__ */ new Map();
|
|
1568
|
-
for (const t of tools) {
|
|
1569
|
-
toolMap.set(t.definition.function.name, t);
|
|
1570
|
-
}
|
|
1571
1356
|
function getAllToolDefs() {
|
|
1572
1357
|
return tools.map((t) => t.definition);
|
|
1573
1358
|
}
|
|
@@ -1579,100 +1364,30 @@ async function executeTool(name, args) {
|
|
|
1579
1364
|
function getToolNames() {
|
|
1580
1365
|
return tools.map((t) => t.definition.function.name);
|
|
1581
1366
|
}
|
|
1367
|
+
var tools, toolMap;
|
|
1368
|
+
var init_tools = __esm({
|
|
1369
|
+
"src/agent/tools/index.ts"() {
|
|
1370
|
+
"use strict";
|
|
1371
|
+
init_file_read();
|
|
1372
|
+
init_file_write();
|
|
1373
|
+
init_file_edit();
|
|
1374
|
+
init_bash();
|
|
1375
|
+
init_grep();
|
|
1376
|
+
init_list_files();
|
|
1377
|
+
init_sandbox();
|
|
1378
|
+
tools = [file_read_exports, file_write_exports, file_edit_exports, bash_exports, grep_exports, list_files_exports, sandbox_exports];
|
|
1379
|
+
toolMap = /* @__PURE__ */ new Map();
|
|
1380
|
+
for (const t of tools) {
|
|
1381
|
+
toolMap.set(t.definition.function.name, t);
|
|
1382
|
+
}
|
|
1383
|
+
}
|
|
1384
|
+
});
|
|
1582
1385
|
|
|
1583
1386
|
// src/mcp/client.ts
|
|
1584
1387
|
import { spawn } from "child_process";
|
|
1585
1388
|
import { existsSync as existsSync3, readFileSync as readFileSync4 } from "fs";
|
|
1586
1389
|
import { join as join3 } from "path";
|
|
1587
1390
|
import { createInterface as createInterface4 } from "readline";
|
|
1588
|
-
var McpClient = class {
|
|
1589
|
-
process = null;
|
|
1590
|
-
requestId = 0;
|
|
1591
|
-
pending = /* @__PURE__ */ new Map();
|
|
1592
|
-
serverName;
|
|
1593
|
-
config;
|
|
1594
|
-
tools = [];
|
|
1595
|
-
constructor(serverName, config) {
|
|
1596
|
-
this.serverName = serverName;
|
|
1597
|
-
this.config = config;
|
|
1598
|
-
}
|
|
1599
|
-
async start() {
|
|
1600
|
-
this.process = spawn(this.config.command, this.config.args ?? [], {
|
|
1601
|
-
stdio: ["pipe", "pipe", "pipe"],
|
|
1602
|
-
env: { ...process.env, ...this.config.env }
|
|
1603
|
-
});
|
|
1604
|
-
const rl = createInterface4({ input: this.process.stdout });
|
|
1605
|
-
rl.on("line", (line) => {
|
|
1606
|
-
try {
|
|
1607
|
-
const msg = JSON.parse(line);
|
|
1608
|
-
if (msg.id !== void 0 && this.pending.has(msg.id)) {
|
|
1609
|
-
const p = this.pending.get(msg.id);
|
|
1610
|
-
this.pending.delete(msg.id);
|
|
1611
|
-
if (msg.error) {
|
|
1612
|
-
p.reject(new Error(msg.error.message));
|
|
1613
|
-
} else {
|
|
1614
|
-
p.resolve(msg.result);
|
|
1615
|
-
}
|
|
1616
|
-
}
|
|
1617
|
-
} catch {
|
|
1618
|
-
}
|
|
1619
|
-
});
|
|
1620
|
-
this.process.on("error", (err) => {
|
|
1621
|
-
console.error(`MCP [${this.serverName}] \uD504\uB85C\uC138\uC2A4 \uC624\uB958:`, err.message);
|
|
1622
|
-
});
|
|
1623
|
-
await this.send("initialize", {
|
|
1624
|
-
protocolVersion: "2024-11-05",
|
|
1625
|
-
capabilities: {},
|
|
1626
|
-
clientInfo: { name: "open-xgen", version: "0.3.0" }
|
|
1627
|
-
});
|
|
1628
|
-
await this.send("notifications/initialized", {});
|
|
1629
|
-
}
|
|
1630
|
-
send(method, params) {
|
|
1631
|
-
return new Promise((resolve, reject) => {
|
|
1632
|
-
const id = ++this.requestId;
|
|
1633
|
-
const request = { jsonrpc: "2.0", id, method, params };
|
|
1634
|
-
this.pending.set(id, { resolve, reject });
|
|
1635
|
-
const timeout = setTimeout(() => {
|
|
1636
|
-
this.pending.delete(id);
|
|
1637
|
-
reject(new Error(`MCP \uC694\uCCAD \uD0C0\uC784\uC544\uC6C3: ${method}`));
|
|
1638
|
-
}, 15e3);
|
|
1639
|
-
this.pending.set(id, {
|
|
1640
|
-
resolve: (v) => {
|
|
1641
|
-
clearTimeout(timeout);
|
|
1642
|
-
resolve(v);
|
|
1643
|
-
},
|
|
1644
|
-
reject: (e) => {
|
|
1645
|
-
clearTimeout(timeout);
|
|
1646
|
-
reject(e);
|
|
1647
|
-
}
|
|
1648
|
-
});
|
|
1649
|
-
this.process?.stdin?.write(JSON.stringify(request) + "\n");
|
|
1650
|
-
});
|
|
1651
|
-
}
|
|
1652
|
-
async listTools() {
|
|
1653
|
-
const result = await this.send("tools/list", {});
|
|
1654
|
-
this.tools = result.tools ?? [];
|
|
1655
|
-
return this.tools;
|
|
1656
|
-
}
|
|
1657
|
-
async callTool(name, args) {
|
|
1658
|
-
const result = await this.send("tools/call", { name, arguments: args });
|
|
1659
|
-
return result.content?.map((c) => c.text ?? "").join("\n") ?? "";
|
|
1660
|
-
}
|
|
1661
|
-
getOpenAITools() {
|
|
1662
|
-
return this.tools.map((t) => ({
|
|
1663
|
-
type: "function",
|
|
1664
|
-
function: {
|
|
1665
|
-
name: `mcp_${this.serverName}_${t.name}`,
|
|
1666
|
-
description: `[MCP:${this.serverName}] ${t.description ?? t.name}`,
|
|
1667
|
-
parameters: t.inputSchema ?? { type: "object", properties: {} }
|
|
1668
|
-
}
|
|
1669
|
-
}));
|
|
1670
|
-
}
|
|
1671
|
-
stop() {
|
|
1672
|
-
this.process?.kill();
|
|
1673
|
-
this.process = null;
|
|
1674
|
-
}
|
|
1675
|
-
};
|
|
1676
1391
|
function loadMcpConfig(dir) {
|
|
1677
1392
|
const searchPaths = [
|
|
1678
1393
|
dir ? join3(dir, ".mcp.json") : null,
|
|
@@ -1690,69 +1405,419 @@ function loadMcpConfig(dir) {
|
|
|
1690
1405
|
}
|
|
1691
1406
|
return null;
|
|
1692
1407
|
}
|
|
1693
|
-
var McpManager
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1408
|
+
var McpClient, McpManager;
|
|
1409
|
+
var init_client2 = __esm({
|
|
1410
|
+
"src/mcp/client.ts"() {
|
|
1411
|
+
"use strict";
|
|
1412
|
+
McpClient = class {
|
|
1413
|
+
process = null;
|
|
1414
|
+
requestId = 0;
|
|
1415
|
+
pending = /* @__PURE__ */ new Map();
|
|
1416
|
+
serverName;
|
|
1417
|
+
config;
|
|
1418
|
+
tools = [];
|
|
1419
|
+
constructor(serverName, config) {
|
|
1420
|
+
this.serverName = serverName;
|
|
1421
|
+
this.config = config;
|
|
1705
1422
|
}
|
|
1706
|
-
|
|
1423
|
+
async start() {
|
|
1424
|
+
this.process = spawn(this.config.command, this.config.args ?? [], {
|
|
1425
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
1426
|
+
env: { ...process.env, ...this.config.env }
|
|
1427
|
+
});
|
|
1428
|
+
const rl = createInterface4({ input: this.process.stdout });
|
|
1429
|
+
rl.on("line", (line) => {
|
|
1430
|
+
try {
|
|
1431
|
+
const msg = JSON.parse(line);
|
|
1432
|
+
if (msg.id !== void 0 && this.pending.has(msg.id)) {
|
|
1433
|
+
const p = this.pending.get(msg.id);
|
|
1434
|
+
this.pending.delete(msg.id);
|
|
1435
|
+
if (msg.error) {
|
|
1436
|
+
p.reject(new Error(msg.error.message));
|
|
1437
|
+
} else {
|
|
1438
|
+
p.resolve(msg.result);
|
|
1439
|
+
}
|
|
1440
|
+
}
|
|
1441
|
+
} catch {
|
|
1442
|
+
}
|
|
1443
|
+
});
|
|
1444
|
+
this.process.on("error", (err) => {
|
|
1445
|
+
console.error(`MCP [${this.serverName}] \uD504\uB85C\uC138\uC2A4 \uC624\uB958:`, err.message);
|
|
1446
|
+
});
|
|
1447
|
+
await this.send("initialize", {
|
|
1448
|
+
protocolVersion: "2024-11-05",
|
|
1449
|
+
capabilities: {},
|
|
1450
|
+
clientInfo: { name: "open-xgen", version: "0.3.0" }
|
|
1451
|
+
});
|
|
1452
|
+
await this.send("notifications/initialized", {});
|
|
1453
|
+
}
|
|
1454
|
+
send(method, params) {
|
|
1455
|
+
return new Promise((resolve, reject) => {
|
|
1456
|
+
const id = ++this.requestId;
|
|
1457
|
+
const request = { jsonrpc: "2.0", id, method, params };
|
|
1458
|
+
this.pending.set(id, { resolve, reject });
|
|
1459
|
+
const timeout = setTimeout(() => {
|
|
1460
|
+
this.pending.delete(id);
|
|
1461
|
+
reject(new Error(`MCP \uC694\uCCAD \uD0C0\uC784\uC544\uC6C3: ${method}`));
|
|
1462
|
+
}, 15e3);
|
|
1463
|
+
this.pending.set(id, {
|
|
1464
|
+
resolve: (v) => {
|
|
1465
|
+
clearTimeout(timeout);
|
|
1466
|
+
resolve(v);
|
|
1467
|
+
},
|
|
1468
|
+
reject: (e) => {
|
|
1469
|
+
clearTimeout(timeout);
|
|
1470
|
+
reject(e);
|
|
1471
|
+
}
|
|
1472
|
+
});
|
|
1473
|
+
this.process?.stdin?.write(JSON.stringify(request) + "\n");
|
|
1474
|
+
});
|
|
1475
|
+
}
|
|
1476
|
+
async listTools() {
|
|
1477
|
+
const result = await this.send("tools/list", {});
|
|
1478
|
+
this.tools = result.tools ?? [];
|
|
1479
|
+
return this.tools;
|
|
1480
|
+
}
|
|
1481
|
+
async callTool(name, args) {
|
|
1482
|
+
const result = await this.send("tools/call", { name, arguments: args });
|
|
1483
|
+
return result.content?.map((c) => c.text ?? "").join("\n") ?? "";
|
|
1484
|
+
}
|
|
1485
|
+
getOpenAITools() {
|
|
1486
|
+
return this.tools.map((t) => ({
|
|
1487
|
+
type: "function",
|
|
1488
|
+
function: {
|
|
1489
|
+
name: `mcp_${this.serverName}_${t.name}`,
|
|
1490
|
+
description: `[MCP:${this.serverName}] ${t.description ?? t.name}`,
|
|
1491
|
+
parameters: t.inputSchema ?? { type: "object", properties: {} }
|
|
1492
|
+
}
|
|
1493
|
+
}));
|
|
1494
|
+
}
|
|
1495
|
+
stop() {
|
|
1496
|
+
this.process?.kill();
|
|
1497
|
+
this.process = null;
|
|
1498
|
+
}
|
|
1499
|
+
};
|
|
1500
|
+
McpManager = class {
|
|
1501
|
+
clients = /* @__PURE__ */ new Map();
|
|
1502
|
+
async startAll(config) {
|
|
1503
|
+
for (const [name, serverConfig] of Object.entries(config.mcpServers)) {
|
|
1504
|
+
if (serverConfig.type !== "stdio") continue;
|
|
1505
|
+
try {
|
|
1506
|
+
const client2 = new McpClient(name, serverConfig);
|
|
1507
|
+
await client2.start();
|
|
1508
|
+
await client2.listTools();
|
|
1509
|
+
this.clients.set(name, client2);
|
|
1510
|
+
} catch (err) {
|
|
1511
|
+
console.error(`MCP [${name}] \uC2DC\uC791 \uC2E4\uD328:`, err.message);
|
|
1512
|
+
}
|
|
1513
|
+
}
|
|
1514
|
+
}
|
|
1515
|
+
getAllTools() {
|
|
1516
|
+
const tools2 = [];
|
|
1517
|
+
for (const client2 of this.clients.values()) {
|
|
1518
|
+
tools2.push(...client2.getOpenAITools());
|
|
1519
|
+
}
|
|
1520
|
+
return tools2;
|
|
1521
|
+
}
|
|
1522
|
+
async callTool(fullName, args) {
|
|
1523
|
+
const parts = fullName.split("_");
|
|
1524
|
+
if (parts.length < 3 || parts[0] !== "mcp") return `Unknown MCP tool: ${fullName}`;
|
|
1525
|
+
const serverName = parts[1];
|
|
1526
|
+
const toolName = parts.slice(2).join("_");
|
|
1527
|
+
const client2 = this.clients.get(serverName);
|
|
1528
|
+
if (!client2) return `MCP \uC11C\uBC84\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${serverName}`;
|
|
1529
|
+
return client2.callTool(toolName, args);
|
|
1530
|
+
}
|
|
1531
|
+
isMcpTool(name) {
|
|
1532
|
+
return name.startsWith("mcp_");
|
|
1533
|
+
}
|
|
1534
|
+
stopAll() {
|
|
1535
|
+
for (const client2 of this.clients.values()) {
|
|
1536
|
+
client2.stop();
|
|
1537
|
+
}
|
|
1538
|
+
this.clients.clear();
|
|
1539
|
+
}
|
|
1540
|
+
get serverCount() {
|
|
1541
|
+
return this.clients.size;
|
|
1542
|
+
}
|
|
1543
|
+
getServerNames() {
|
|
1544
|
+
return [...this.clients.keys()];
|
|
1545
|
+
}
|
|
1546
|
+
};
|
|
1547
|
+
}
|
|
1548
|
+
});
|
|
1549
|
+
|
|
1550
|
+
// src/commands/home.ts
|
|
1551
|
+
var home_exports = {};
|
|
1552
|
+
__export(home_exports, {
|
|
1553
|
+
homeMenu: () => homeMenu
|
|
1554
|
+
});
|
|
1555
|
+
import chalk11 from "chalk";
|
|
1556
|
+
import { createInterface as createInterface5 } from "readline";
|
|
1557
|
+
function prompt3(question) {
|
|
1558
|
+
return new Promise((resolve) => {
|
|
1559
|
+
const rl = createInterface5({ input: process.stdin, output: process.stdout });
|
|
1560
|
+
rl.question(question, (answer) => {
|
|
1561
|
+
rl.close();
|
|
1562
|
+
resolve(answer.trim());
|
|
1563
|
+
});
|
|
1564
|
+
});
|
|
1565
|
+
}
|
|
1566
|
+
function showStatus() {
|
|
1567
|
+
const provider = getDefaultProvider();
|
|
1568
|
+
const server = getServer();
|
|
1569
|
+
const auth = getAuth();
|
|
1570
|
+
console.log(chalk11.gray(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
1571
|
+
console.log(chalk11.gray(" \uC0C1\uD0DC:"));
|
|
1572
|
+
if (provider) {
|
|
1573
|
+
console.log(` AI \uC5D0\uC774\uC804\uD2B8 ${chalk11.green("\u25CF")} ${provider.name} (${provider.model})`);
|
|
1574
|
+
} else {
|
|
1575
|
+
console.log(` AI \uC5D0\uC774\uC804\uD2B8 ${chalk11.red("\u25CB")} \uBBF8\uC124\uC815`);
|
|
1576
|
+
}
|
|
1577
|
+
if (server && auth) {
|
|
1578
|
+
console.log(` XGEN \uC11C\uBC84 ${chalk11.green("\u25CF")} ${server} (${auth.username})`);
|
|
1579
|
+
} else if (server) {
|
|
1580
|
+
console.log(` XGEN \uC11C\uBC84 ${chalk11.yellow("\u25CB")} ${server} (\uB85C\uADF8\uC778 \uD544\uC694)`);
|
|
1581
|
+
} else {
|
|
1582
|
+
console.log(` XGEN \uC11C\uBC84 ${chalk11.red("\u25CB")} \uBBF8\uC124\uC815`);
|
|
1707
1583
|
}
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1584
|
+
console.log(chalk11.gray(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n"));
|
|
1585
|
+
}
|
|
1586
|
+
async function homeMenu() {
|
|
1587
|
+
const provider = getDefaultProvider();
|
|
1588
|
+
const server = getServer();
|
|
1589
|
+
const auth = getAuth();
|
|
1590
|
+
console.log(chalk11.cyan(`
|
|
1591
|
+
\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588 \u2588\u2588
|
|
1592
|
+
\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588 \u2588\u2588
|
|
1593
|
+
\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588
|
|
1594
|
+
\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588
|
|
1595
|
+
\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588`));
|
|
1596
|
+
console.log(chalk11.white.bold(`
|
|
1597
|
+
\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588 \u2588\u2588
|
|
1598
|
+
\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588 \u2588\u2588
|
|
1599
|
+
\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588
|
|
1600
|
+
\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588
|
|
1601
|
+
\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588`));
|
|
1602
|
+
console.log(chalk11.gray(` v0.3.0
|
|
1603
|
+
`));
|
|
1604
|
+
showStatus();
|
|
1605
|
+
while (true) {
|
|
1606
|
+
const items = [];
|
|
1607
|
+
items.push({
|
|
1608
|
+
key: "1",
|
|
1609
|
+
label: provider ? `AI \uC5D0\uC774\uC804\uD2B8 \uC2DC\uC791 ${chalk11.gray(`(${provider.name})`)}` : `AI \uC5D0\uC774\uC804\uD2B8 \uC124\uC815 + \uC2DC\uC791`,
|
|
1610
|
+
available: true,
|
|
1611
|
+
action: async () => {
|
|
1612
|
+
await agentRepl();
|
|
1613
|
+
}
|
|
1614
|
+
});
|
|
1615
|
+
if (server && auth) {
|
|
1616
|
+
items.push({
|
|
1617
|
+
key: "2",
|
|
1618
|
+
label: `\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uCC44\uD305 ${chalk11.gray(`(${auth.username}@${server.replace("https://", "")})`)}`,
|
|
1619
|
+
available: true,
|
|
1620
|
+
action: async () => {
|
|
1621
|
+
await chat();
|
|
1622
|
+
}
|
|
1623
|
+
});
|
|
1624
|
+
items.push({
|
|
1625
|
+
key: "3",
|
|
1626
|
+
label: "\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uBAA9\uB85D",
|
|
1627
|
+
available: true,
|
|
1628
|
+
action: async () => {
|
|
1629
|
+
const { workflowList: workflowList2 } = await Promise.resolve().then(() => (init_list(), list_exports));
|
|
1630
|
+
await workflowList2({ detail: false });
|
|
1631
|
+
return;
|
|
1632
|
+
}
|
|
1633
|
+
});
|
|
1634
|
+
} else {
|
|
1635
|
+
items.push({
|
|
1636
|
+
key: "2",
|
|
1637
|
+
label: "XGEN \uC11C\uBC84 \uC5F0\uACB0 + \uB85C\uADF8\uC778",
|
|
1638
|
+
available: true,
|
|
1639
|
+
action: async () => {
|
|
1640
|
+
await serverSetup();
|
|
1641
|
+
}
|
|
1642
|
+
});
|
|
1643
|
+
}
|
|
1644
|
+
items.push({
|
|
1645
|
+
key: String(items.length + 1),
|
|
1646
|
+
label: "\uD504\uB85C\uBC14\uC774\uB354 \uAD00\uB9AC",
|
|
1647
|
+
available: true,
|
|
1648
|
+
action: async () => {
|
|
1649
|
+
await providerMenu();
|
|
1650
|
+
}
|
|
1651
|
+
});
|
|
1652
|
+
items.push({
|
|
1653
|
+
key: String(items.length + 1),
|
|
1654
|
+
label: "\uC124\uC815 \uBCF4\uAE30",
|
|
1655
|
+
available: true,
|
|
1656
|
+
action: async () => {
|
|
1657
|
+
showStatus();
|
|
1658
|
+
const cfg = await Promise.resolve().then(() => (init_store(), store_exports));
|
|
1659
|
+
const config = cfg.getConfig();
|
|
1660
|
+
console.log(chalk11.gray(" \uC124\uC815 \uD30C\uC77C: ~/.xgen/\n"));
|
|
1661
|
+
console.log(chalk11.gray(` \uC11C\uBC84: ${config.server ?? "(\uC5C6\uC74C)"}`));
|
|
1662
|
+
console.log(chalk11.gray(` \uD14C\uB9C8: ${config.theme}`));
|
|
1663
|
+
console.log(chalk11.gray(` \uC2A4\uD2B8\uB9BC \uB85C\uADF8: ${config.streamLogs}
|
|
1664
|
+
`));
|
|
1665
|
+
}
|
|
1666
|
+
});
|
|
1667
|
+
items.push({
|
|
1668
|
+
key: "q",
|
|
1669
|
+
label: "\uC885\uB8CC",
|
|
1670
|
+
available: true,
|
|
1671
|
+
action: async () => {
|
|
1672
|
+
process.exit(0);
|
|
1673
|
+
}
|
|
1674
|
+
});
|
|
1675
|
+
console.log(chalk11.bold(" \uBB58 \uD558\uC2DC\uACA0\uC2B5\uB2C8\uAE4C?\n"));
|
|
1676
|
+
for (const item of items) {
|
|
1677
|
+
console.log(` ${chalk11.cyan(item.key + ")")} ${item.label}`);
|
|
1678
|
+
}
|
|
1679
|
+
console.log();
|
|
1680
|
+
const choice = await prompt3(chalk11.white(" \uC120\uD0DD: "));
|
|
1681
|
+
if (choice === "q" || choice === "exit") {
|
|
1682
|
+
console.log(chalk11.gray("\n \uC548\uB155\uD788.\n"));
|
|
1683
|
+
break;
|
|
1684
|
+
}
|
|
1685
|
+
const selected = items.find((i) => i.key === choice);
|
|
1686
|
+
if (!selected) {
|
|
1687
|
+
console.log(chalk11.red(" \uC798\uBABB\uB41C \uC120\uD0DD\uC785\uB2C8\uB2E4.\n"));
|
|
1688
|
+
continue;
|
|
1689
|
+
}
|
|
1690
|
+
try {
|
|
1691
|
+
await selected.action();
|
|
1692
|
+
} catch (err) {
|
|
1693
|
+
console.log(chalk11.red(`
|
|
1694
|
+
\uC624\uB958: ${err.message}
|
|
1695
|
+
`));
|
|
1712
1696
|
}
|
|
1713
|
-
|
|
1697
|
+
console.log();
|
|
1698
|
+
showStatus();
|
|
1714
1699
|
}
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1700
|
+
}
|
|
1701
|
+
async function serverSetup() {
|
|
1702
|
+
console.log(chalk11.cyan.bold("\n XGEN \uC11C\uBC84 \uC5F0\uACB0\n"));
|
|
1703
|
+
const currentServer = getServer();
|
|
1704
|
+
const urlInput = await prompt3(
|
|
1705
|
+
chalk11.white(` \uC11C\uBC84 URL${currentServer ? ` [${currentServer}]` : ""}: `)
|
|
1706
|
+
);
|
|
1707
|
+
const url = urlInput || currentServer;
|
|
1708
|
+
if (!url) {
|
|
1709
|
+
console.log(chalk11.red(" URL\uC774 \uD544\uC694\uD569\uB2C8\uB2E4.\n"));
|
|
1710
|
+
return;
|
|
1723
1711
|
}
|
|
1724
|
-
|
|
1725
|
-
|
|
1712
|
+
const { setServer: setServer2 } = await Promise.resolve().then(() => (init_store(), store_exports));
|
|
1713
|
+
setServer2(url);
|
|
1714
|
+
console.log(chalk11.green(` \u2713 \uC11C\uBC84 \uC124\uC815: ${url}
|
|
1715
|
+
`));
|
|
1716
|
+
console.log(chalk11.bold(" \uB85C\uADF8\uC778\n"));
|
|
1717
|
+
const email = await prompt3(chalk11.white(" \uC774\uBA54\uC77C: "));
|
|
1718
|
+
const password = await prompt3(chalk11.white(" \uBE44\uBC00\uBC88\uD638: "));
|
|
1719
|
+
if (!email || !password) {
|
|
1720
|
+
console.log(chalk11.red(" \uC774\uBA54\uC77C\uACFC \uBE44\uBC00\uBC88\uD638\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4.\n"));
|
|
1721
|
+
return;
|
|
1726
1722
|
}
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1723
|
+
try {
|
|
1724
|
+
const { apiLogin: apiLogin2 } = await Promise.resolve().then(() => (init_auth(), auth_exports));
|
|
1725
|
+
const { setAuth: setAuth2 } = await Promise.resolve().then(() => (init_store(), store_exports));
|
|
1726
|
+
const result = await apiLogin2(email, password);
|
|
1727
|
+
if (result.success && result.access_token) {
|
|
1728
|
+
setAuth2({
|
|
1729
|
+
accessToken: result.access_token,
|
|
1730
|
+
refreshToken: result.refresh_token ?? "",
|
|
1731
|
+
userId: result.user_id ?? "",
|
|
1732
|
+
username: result.username ?? "",
|
|
1733
|
+
isAdmin: false,
|
|
1734
|
+
expiresAt: null
|
|
1735
|
+
});
|
|
1736
|
+
console.log(chalk11.green(` \u2713 \uB85C\uADF8\uC778 \uC131\uACF5! ${result.username ?? email}
|
|
1737
|
+
`));
|
|
1738
|
+
} else {
|
|
1739
|
+
console.log(chalk11.red(` \u2717 \uB85C\uADF8\uC778 \uC2E4\uD328: ${result.message}
|
|
1740
|
+
`));
|
|
1730
1741
|
}
|
|
1731
|
-
|
|
1742
|
+
} catch (err) {
|
|
1743
|
+
console.log(chalk11.red(` \u2717 \uB85C\uADF8\uC778 \uC2E4\uD328: ${err.message}
|
|
1744
|
+
`));
|
|
1732
1745
|
}
|
|
1733
|
-
|
|
1734
|
-
|
|
1746
|
+
}
|
|
1747
|
+
async function providerMenu() {
|
|
1748
|
+
const { getProviders: getProviders2, getDefaultProvider: getDefault } = await Promise.resolve().then(() => (init_store(), store_exports));
|
|
1749
|
+
const providers = getProviders2();
|
|
1750
|
+
const defaultP = getDefault();
|
|
1751
|
+
console.log(chalk11.cyan.bold("\n \uD504\uB85C\uBC14\uC774\uB354 \uAD00\uB9AC\n"));
|
|
1752
|
+
if (providers.length > 0) {
|
|
1753
|
+
for (const p of providers) {
|
|
1754
|
+
const mark = p.id === defaultP?.id ? chalk11.green("\u25CF ") : chalk11.gray(" ");
|
|
1755
|
+
console.log(` ${mark}${p.name} ${chalk11.gray(`(${p.type} \u2014 ${p.model})`)}`);
|
|
1756
|
+
}
|
|
1757
|
+
console.log();
|
|
1735
1758
|
}
|
|
1736
|
-
|
|
1737
|
-
|
|
1759
|
+
console.log(` ${chalk11.cyan("1)")} \uC0C8 \uD504\uB85C\uBC14\uC774\uB354 \uCD94\uAC00`);
|
|
1760
|
+
if (providers.length > 1) {
|
|
1761
|
+
console.log(` ${chalk11.cyan("2)")} \uAE30\uBCF8 \uD504\uB85C\uBC14\uC774\uB354 \uBCC0\uACBD`);
|
|
1738
1762
|
}
|
|
1739
|
-
|
|
1763
|
+
if (providers.length > 0) {
|
|
1764
|
+
console.log(` ${chalk11.cyan("3)")} \uD504\uB85C\uBC14\uC774\uB354 \uC0AD\uC81C`);
|
|
1765
|
+
}
|
|
1766
|
+
console.log(` ${chalk11.cyan("b)")} \uB3CC\uC544\uAC00\uAE30`);
|
|
1767
|
+
console.log();
|
|
1768
|
+
const choice = await prompt3(chalk11.white(" \uC120\uD0DD: "));
|
|
1769
|
+
if (choice === "1") {
|
|
1770
|
+
await guidedProviderSetup();
|
|
1771
|
+
} else if (choice === "2" && providers.length > 1) {
|
|
1772
|
+
console.log();
|
|
1773
|
+
providers.forEach((p, i) => {
|
|
1774
|
+
console.log(` ${chalk11.cyan(`${i + 1})`)} ${p.name} (${p.model})`);
|
|
1775
|
+
});
|
|
1776
|
+
console.log();
|
|
1777
|
+
const pc = await prompt3(chalk11.white(" \uBC88\uD638: "));
|
|
1778
|
+
const pi = parseInt(pc) - 1;
|
|
1779
|
+
if (pi >= 0 && pi < providers.length) {
|
|
1780
|
+
const { setDefaultProvider: setDef } = await Promise.resolve().then(() => (init_store(), store_exports));
|
|
1781
|
+
setDef(providers[pi].id);
|
|
1782
|
+
console.log(chalk11.green(` \u2713 \uAE30\uBCF8 \uD504\uB85C\uBC14\uC774\uB354: ${providers[pi].name}
|
|
1783
|
+
`));
|
|
1784
|
+
}
|
|
1785
|
+
} else if (choice === "3" && providers.length > 0) {
|
|
1786
|
+
console.log();
|
|
1787
|
+
providers.forEach((p, i) => {
|
|
1788
|
+
console.log(` ${chalk11.cyan(`${i + 1})`)} ${p.name} (${p.model})`);
|
|
1789
|
+
});
|
|
1790
|
+
console.log();
|
|
1791
|
+
const dc = await prompt3(chalk11.white(" \uC0AD\uC81C\uD560 \uBC88\uD638: "));
|
|
1792
|
+
const di = parseInt(dc) - 1;
|
|
1793
|
+
if (di >= 0 && di < providers.length) {
|
|
1794
|
+
const { removeProvider: rmProv } = await Promise.resolve().then(() => (init_store(), store_exports));
|
|
1795
|
+
rmProv(providers[di].id);
|
|
1796
|
+
console.log(chalk11.green(` \u2713 \uC0AD\uC81C\uB428: ${providers[di].name}
|
|
1797
|
+
`));
|
|
1798
|
+
}
|
|
1799
|
+
}
|
|
1800
|
+
}
|
|
1801
|
+
var init_home = __esm({
|
|
1802
|
+
"src/commands/home.ts"() {
|
|
1803
|
+
"use strict";
|
|
1804
|
+
init_store();
|
|
1805
|
+
init_agent();
|
|
1806
|
+
init_chat();
|
|
1807
|
+
init_provider();
|
|
1808
|
+
}
|
|
1809
|
+
});
|
|
1740
1810
|
|
|
1741
1811
|
// src/commands/agent.ts
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
You can also use MCP (Model Context Protocol) tools if available.
|
|
1745
|
-
Always respond in the same language as the user.
|
|
1746
|
-
When using tools, be concise about what you're doing.
|
|
1747
|
-
For file edits, show what you changed briefly.
|
|
1748
|
-
For sandbox_run, you can install npm/pip packages and run isolated code.`;
|
|
1749
|
-
var mcpManager = null;
|
|
1812
|
+
import chalk12 from "chalk";
|
|
1813
|
+
import { createInterface as createInterface6 } from "readline";
|
|
1750
1814
|
async function agentRepl() {
|
|
1751
|
-
|
|
1815
|
+
let provider = getDefaultProvider();
|
|
1752
1816
|
if (!provider) {
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1817
|
+
provider = await guidedProviderSetup();
|
|
1818
|
+
if (!provider) {
|
|
1819
|
+
process.exit(1);
|
|
1820
|
+
}
|
|
1756
1821
|
}
|
|
1757
1822
|
const client2 = createLLMClient(provider);
|
|
1758
1823
|
const builtinTools = getAllToolDefs();
|
|
@@ -1771,138 +1836,609 @@ async function agentRepl() {
|
|
|
1771
1836
|
} catch {
|
|
1772
1837
|
}
|
|
1773
1838
|
}
|
|
1774
|
-
const messages = [{ role: "system", content: SYSTEM_PROMPT }];
|
|
1775
|
-
console.log(
|
|
1776
|
-
console.log(
|
|
1777
|
-
console.log(
|
|
1778
|
-
console.log(
|
|
1779
|
-
if (mcpManager && mcpManager.serverCount > 0) {
|
|
1780
|
-
console.log(
|
|
1839
|
+
const messages = [{ role: "system", content: SYSTEM_PROMPT }];
|
|
1840
|
+
console.log(chalk12.cyan.bold("\n OPEN XGEN Agent"));
|
|
1841
|
+
console.log(chalk12.gray(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
1842
|
+
console.log(chalk12.gray(` \uD504\uB85C\uBC14\uC774\uB354: ${provider.name} (${provider.model})`));
|
|
1843
|
+
console.log(chalk12.gray(` \uB3C4\uAD6C: ${getToolNames().join(", ")}`));
|
|
1844
|
+
if (mcpManager && mcpManager.serverCount > 0) {
|
|
1845
|
+
console.log(chalk12.gray(` MCP: ${mcpManager.getServerNames().join(", ")} (${mcpManager.getAllTools().length}\uAC1C \uB3C4\uAD6C)`));
|
|
1846
|
+
}
|
|
1847
|
+
console.log(chalk12.gray(` \uCEE4\uB9E8\uB4DC: /tools /provider /model /mcp /clear /home /exit`));
|
|
1848
|
+
console.log();
|
|
1849
|
+
const rl = createInterface6({ input: process.stdin, output: process.stdout });
|
|
1850
|
+
const ask = () => new Promise((resolve) => rl.question(chalk12.green("\u276F "), (a) => resolve(a.trim())));
|
|
1851
|
+
process.on("SIGINT", () => {
|
|
1852
|
+
console.log(chalk12.gray("\n\uC885\uB8CC\uD569\uB2C8\uB2E4."));
|
|
1853
|
+
mcpManager?.stopAll();
|
|
1854
|
+
rl.close();
|
|
1855
|
+
process.exit(0);
|
|
1856
|
+
});
|
|
1857
|
+
while (true) {
|
|
1858
|
+
const input = await ask();
|
|
1859
|
+
if (!input) continue;
|
|
1860
|
+
if (input === "exit" || input === "/exit") {
|
|
1861
|
+
console.log(chalk12.gray("\uC885\uB8CC\uD569\uB2C8\uB2E4."));
|
|
1862
|
+
mcpManager?.stopAll();
|
|
1863
|
+
rl.close();
|
|
1864
|
+
break;
|
|
1865
|
+
}
|
|
1866
|
+
if (input === "/clear") {
|
|
1867
|
+
messages.length = 1;
|
|
1868
|
+
console.log(chalk12.gray("\uB300\uD654 \uCD08\uAE30\uD654\uB428.\n"));
|
|
1869
|
+
continue;
|
|
1870
|
+
}
|
|
1871
|
+
if (input === "/tools") {
|
|
1872
|
+
console.log(chalk12.bold("\n\uB0B4\uC7A5 \uB3C4\uAD6C:"), getToolNames().join(", "));
|
|
1873
|
+
if (mcpManager && mcpManager.serverCount > 0) {
|
|
1874
|
+
console.log(chalk12.bold("MCP \uB3C4\uAD6C:"), mcpManager.getAllTools().map((t) => t.function.name).join(", "));
|
|
1875
|
+
}
|
|
1876
|
+
console.log();
|
|
1877
|
+
continue;
|
|
1878
|
+
}
|
|
1879
|
+
if (input === "/provider") {
|
|
1880
|
+
console.log(chalk12.gray(`\uD604\uC7AC: ${provider.name} (${provider.model})`));
|
|
1881
|
+
console.log(chalk12.gray(`\uBCC0\uACBD: xgen provider add / xgen provider use <id>
|
|
1882
|
+
`));
|
|
1883
|
+
continue;
|
|
1884
|
+
}
|
|
1885
|
+
if (input === "/model") {
|
|
1886
|
+
const { getProviders: gp } = await Promise.resolve().then(() => (init_store(), store_exports));
|
|
1887
|
+
const all = gp();
|
|
1888
|
+
if (all.length > 0) {
|
|
1889
|
+
console.log(chalk12.bold("\n \uB4F1\uB85D\uB41C \uD504\uB85C\uBC14\uC774\uB354:\n"));
|
|
1890
|
+
all.forEach((p, i) => {
|
|
1891
|
+
const mark = p.id === provider.id ? chalk12.green("\u25CF ") : " ";
|
|
1892
|
+
console.log(` ${mark}${i + 1}) ${p.name} (${p.model})`);
|
|
1893
|
+
});
|
|
1894
|
+
console.log(chalk12.gray("\n \uBCC0\uACBD\uD558\uB824\uBA74 exit \uD6C4 xgen provider use <id>\n"));
|
|
1895
|
+
}
|
|
1896
|
+
continue;
|
|
1897
|
+
}
|
|
1898
|
+
if (input === "/home" || input === "/menu") {
|
|
1899
|
+
console.log(chalk12.gray("\uC5D0\uC774\uC804\uD2B8\uB97C \uC885\uB8CC\uD558\uACE0 \uD648\uC73C\uB85C \uB3CC\uC544\uAC11\uB2C8\uB2E4."));
|
|
1900
|
+
mcpManager?.stopAll();
|
|
1901
|
+
rl.close();
|
|
1902
|
+
const { homeMenu: homeMenu2 } = await Promise.resolve().then(() => (init_home(), home_exports));
|
|
1903
|
+
await homeMenu2();
|
|
1904
|
+
return;
|
|
1905
|
+
}
|
|
1906
|
+
if (input === "/mcp") {
|
|
1907
|
+
if (mcpManager && mcpManager.serverCount > 0) {
|
|
1908
|
+
console.log(chalk12.bold("\nMCP \uC11C\uBC84:"), mcpManager.getServerNames().join(", "));
|
|
1909
|
+
console.log(chalk12.gray("\uB3C4\uAD6C:"), mcpManager.getAllTools().map((t) => t.function.name).join(", "));
|
|
1910
|
+
} else {
|
|
1911
|
+
console.log(chalk12.gray("MCP \uC11C\uBC84 \uC5C6\uC74C. .mcp.json\uC744 \uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8\uC5D0 \uCD94\uAC00\uD558\uC138\uC694."));
|
|
1912
|
+
}
|
|
1913
|
+
console.log();
|
|
1914
|
+
continue;
|
|
1915
|
+
}
|
|
1916
|
+
messages.push({ role: "user", content: input });
|
|
1917
|
+
try {
|
|
1918
|
+
await runAgentLoop(client2, provider.model, messages, allTools);
|
|
1919
|
+
} catch (err) {
|
|
1920
|
+
console.log(chalk12.red(`
|
|
1921
|
+
\uC624\uB958: ${err.message}
|
|
1922
|
+
`));
|
|
1923
|
+
}
|
|
1924
|
+
}
|
|
1925
|
+
}
|
|
1926
|
+
async function runAgentLoop(client2, model, messages, tools2) {
|
|
1927
|
+
const MAX_ITERATIONS = 20;
|
|
1928
|
+
for (let i = 0; i < MAX_ITERATIONS; i++) {
|
|
1929
|
+
const result = await streamChat(client2, model, messages, tools2, (delta) => {
|
|
1930
|
+
process.stdout.write(delta);
|
|
1931
|
+
});
|
|
1932
|
+
if (result.content) {
|
|
1933
|
+
process.stdout.write("\n\n");
|
|
1934
|
+
}
|
|
1935
|
+
if (result.toolCalls.length === 0) {
|
|
1936
|
+
if (result.content) {
|
|
1937
|
+
messages.push({ role: "assistant", content: result.content });
|
|
1938
|
+
}
|
|
1939
|
+
return;
|
|
1940
|
+
}
|
|
1941
|
+
messages.push({
|
|
1942
|
+
role: "assistant",
|
|
1943
|
+
content: result.content || null,
|
|
1944
|
+
tool_calls: result.toolCalls.map((tc) => ({
|
|
1945
|
+
id: tc.id,
|
|
1946
|
+
type: "function",
|
|
1947
|
+
function: { name: tc.name, arguments: tc.arguments }
|
|
1948
|
+
}))
|
|
1949
|
+
});
|
|
1950
|
+
for (const tc of result.toolCalls) {
|
|
1951
|
+
let args;
|
|
1952
|
+
try {
|
|
1953
|
+
args = JSON.parse(tc.arguments);
|
|
1954
|
+
} catch {
|
|
1955
|
+
args = {};
|
|
1956
|
+
}
|
|
1957
|
+
console.log(chalk12.gray(` \u2699 ${tc.name}(`), chalk12.dim(summarizeArgs(args)), chalk12.gray(")"));
|
|
1958
|
+
let toolResult;
|
|
1959
|
+
if (mcpManager?.isMcpTool(tc.name)) {
|
|
1960
|
+
toolResult = await mcpManager.callTool(tc.name, args);
|
|
1961
|
+
} else {
|
|
1962
|
+
toolResult = await executeTool(tc.name, args);
|
|
1963
|
+
}
|
|
1964
|
+
const truncated = toolResult.length > 4e3 ? toolResult.slice(0, 4e3) + "\n...(truncated)" : toolResult;
|
|
1965
|
+
messages.push({
|
|
1966
|
+
role: "tool",
|
|
1967
|
+
tool_call_id: tc.id,
|
|
1968
|
+
content: truncated
|
|
1969
|
+
});
|
|
1970
|
+
}
|
|
1971
|
+
}
|
|
1972
|
+
console.log(chalk12.yellow("\n\uCD5C\uB300 \uBC18\uBCF5 \uD69F\uC218\uC5D0 \uB3C4\uB2EC\uD588\uC2B5\uB2C8\uB2E4.\n"));
|
|
1973
|
+
}
|
|
1974
|
+
function summarizeArgs(args) {
|
|
1975
|
+
const parts = [];
|
|
1976
|
+
for (const [k, v] of Object.entries(args)) {
|
|
1977
|
+
const s = String(v);
|
|
1978
|
+
parts.push(`${k}: ${s.length > 40 ? s.slice(0, 40) + "..." : s}`);
|
|
1979
|
+
}
|
|
1980
|
+
return parts.join(", ");
|
|
1981
|
+
}
|
|
1982
|
+
function registerAgentCommand(program2) {
|
|
1983
|
+
program2.command("agent").description("OPEN XGEN AI \uCF54\uB529 \uC5D0\uC774\uC804\uD2B8").action(async () => {
|
|
1984
|
+
await agentRepl();
|
|
1985
|
+
});
|
|
1986
|
+
}
|
|
1987
|
+
var SYSTEM_PROMPT, mcpManager;
|
|
1988
|
+
var init_agent = __esm({
|
|
1989
|
+
"src/commands/agent.ts"() {
|
|
1990
|
+
"use strict";
|
|
1991
|
+
init_store();
|
|
1992
|
+
init_llm();
|
|
1993
|
+
init_tools();
|
|
1994
|
+
init_client2();
|
|
1995
|
+
init_provider();
|
|
1996
|
+
SYSTEM_PROMPT = `You are OPEN XGEN Agent, an AI coding assistant running in the user's terminal.
|
|
1997
|
+
You have access to tools for reading/writing files, executing commands, searching code, and running sandboxed code.
|
|
1998
|
+
You can also use MCP (Model Context Protocol) tools if available.
|
|
1999
|
+
Always respond in the same language as the user.
|
|
2000
|
+
When using tools, be concise about what you're doing.
|
|
2001
|
+
For file edits, show what you changed briefly.
|
|
2002
|
+
For sandbox_run, you can install npm/pip packages and run isolated code.`;
|
|
2003
|
+
mcpManager = null;
|
|
2004
|
+
}
|
|
2005
|
+
});
|
|
2006
|
+
|
|
2007
|
+
// src/index.ts
|
|
2008
|
+
import { Command } from "commander";
|
|
2009
|
+
import chalk15 from "chalk";
|
|
2010
|
+
|
|
2011
|
+
// src/commands/config.ts
|
|
2012
|
+
init_store();
|
|
2013
|
+
init_client();
|
|
2014
|
+
init_format();
|
|
2015
|
+
import chalk2 from "chalk";
|
|
2016
|
+
function registerConfigCommand(program2) {
|
|
2017
|
+
const config = program2.command("config").description("XGEN CLI \uC124\uC815 \uAD00\uB9AC");
|
|
2018
|
+
config.command("set-server <url>").description("XGEN \uC11C\uBC84 URL \uC124\uC815").action((url) => {
|
|
2019
|
+
if (!url.startsWith("http://") && !url.startsWith("https://")) {
|
|
2020
|
+
printError("URL\uC740 http:// \uB610\uB294 https://\uB85C \uC2DC\uC791\uD574\uC57C \uD569\uB2C8\uB2E4");
|
|
2021
|
+
process.exit(1);
|
|
2022
|
+
}
|
|
2023
|
+
setServer(url);
|
|
2024
|
+
resetClient();
|
|
2025
|
+
printSuccess(`\uC11C\uBC84 \uC124\uC815 \uC644\uB8CC: ${chalk2.underline(url)}`);
|
|
2026
|
+
});
|
|
2027
|
+
config.command("get-server").description("\uD604\uC7AC \uC124\uC815\uB41C \uC11C\uBC84 URL \uD655\uC778").action(() => {
|
|
2028
|
+
const server = getServer();
|
|
2029
|
+
if (server) {
|
|
2030
|
+
console.log(server);
|
|
2031
|
+
} else {
|
|
2032
|
+
printError("\uC11C\uBC84\uAC00 \uC124\uC815\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4");
|
|
2033
|
+
console.log(" \uC124\uC815: xgen config set-server <url>");
|
|
2034
|
+
}
|
|
2035
|
+
});
|
|
2036
|
+
config.command("list").description("\uC804\uCCB4 \uC124\uC815 \uD655\uC778").action(() => {
|
|
2037
|
+
const cfg = getConfig();
|
|
2038
|
+
console.log(chalk2.bold("\nXGEN CLI \uC124\uC815"));
|
|
2039
|
+
console.log(chalk2.gray("\u2500".repeat(40)));
|
|
2040
|
+
printKeyValue("\uC11C\uBC84", cfg.server);
|
|
2041
|
+
printKeyValue("\uAE30\uBCF8 \uC6CC\uD06C\uD50C\uB85C\uC6B0", cfg.defaultWorkflow);
|
|
2042
|
+
printKeyValue("\uD14C\uB9C8", cfg.theme);
|
|
2043
|
+
printKeyValue("\uC2A4\uD2B8\uB9BC \uB85C\uADF8", String(cfg.streamLogs));
|
|
2044
|
+
console.log();
|
|
2045
|
+
});
|
|
2046
|
+
config.command("set <key> <value>").description("\uC124\uC815 \uAC12 \uBCC0\uACBD").action((key, value) => {
|
|
2047
|
+
const allowedKeys = ["defaultWorkflow", "theme", "streamLogs"];
|
|
2048
|
+
if (!allowedKeys.includes(key)) {
|
|
2049
|
+
printError(`\uC54C \uC218 \uC5C6\uB294 \uC124\uC815 \uD0A4: ${key}`);
|
|
2050
|
+
console.log(` \uC0AC\uC6A9 \uAC00\uB2A5: ${allowedKeys.join(", ")}`);
|
|
2051
|
+
process.exit(1);
|
|
2052
|
+
}
|
|
2053
|
+
const parsed = key === "streamLogs" ? value === "true" : value;
|
|
2054
|
+
setConfig({ [key]: parsed });
|
|
2055
|
+
printSuccess(`${key} = ${value}`);
|
|
2056
|
+
});
|
|
2057
|
+
}
|
|
2058
|
+
|
|
2059
|
+
// src/commands/login.ts
|
|
2060
|
+
init_auth();
|
|
2061
|
+
init_store();
|
|
2062
|
+
init_format();
|
|
2063
|
+
import chalk3 from "chalk";
|
|
2064
|
+
import { createInterface } from "readline";
|
|
2065
|
+
function prompt(question, hidden = false) {
|
|
2066
|
+
return new Promise((resolve) => {
|
|
2067
|
+
const rl = createInterface({
|
|
2068
|
+
input: process.stdin,
|
|
2069
|
+
output: process.stdout
|
|
2070
|
+
});
|
|
2071
|
+
if (hidden) {
|
|
2072
|
+
process.stdout.write(question);
|
|
2073
|
+
const stdin = process.stdin;
|
|
2074
|
+
const wasRaw = stdin.isRaw;
|
|
2075
|
+
if (stdin.isTTY) stdin.setRawMode(true);
|
|
2076
|
+
let password = "";
|
|
2077
|
+
const onData = (ch) => {
|
|
2078
|
+
const c = ch.toString("utf8");
|
|
2079
|
+
if (c === "\n" || c === "\r" || c === "") {
|
|
2080
|
+
if (stdin.isTTY) stdin.setRawMode(wasRaw ?? false);
|
|
2081
|
+
stdin.removeListener("data", onData);
|
|
2082
|
+
process.stdout.write("\n");
|
|
2083
|
+
rl.close();
|
|
2084
|
+
resolve(password);
|
|
2085
|
+
} else if (c === "") {
|
|
2086
|
+
process.exit(0);
|
|
2087
|
+
} else if (c === "\x7F" || c === "\b") {
|
|
2088
|
+
if (password.length > 0) {
|
|
2089
|
+
password = password.slice(0, -1);
|
|
2090
|
+
process.stdout.write("\b \b");
|
|
2091
|
+
}
|
|
2092
|
+
} else {
|
|
2093
|
+
password += c;
|
|
2094
|
+
process.stdout.write("*");
|
|
2095
|
+
}
|
|
2096
|
+
};
|
|
2097
|
+
stdin.on("data", onData);
|
|
2098
|
+
} else {
|
|
2099
|
+
rl.question(question, (answer) => {
|
|
2100
|
+
rl.close();
|
|
2101
|
+
resolve(answer.trim());
|
|
2102
|
+
});
|
|
2103
|
+
}
|
|
2104
|
+
});
|
|
2105
|
+
}
|
|
2106
|
+
function registerLoginCommand(program2) {
|
|
2107
|
+
program2.command("login").description("XGEN \uC11C\uBC84\uC5D0 \uB85C\uADF8\uC778").option("-e, --email <email>", "\uC774\uBA54\uC77C").option("-p, --password <password>", "\uBE44\uBC00\uBC88\uD638").action(async (opts) => {
|
|
2108
|
+
const server = requireServer();
|
|
2109
|
+
printHeader("XGEN Login");
|
|
2110
|
+
console.log(chalk3.gray(`\uC11C\uBC84: ${server}
|
|
2111
|
+
`));
|
|
2112
|
+
let email = opts.email;
|
|
2113
|
+
let password = opts.password;
|
|
2114
|
+
if (!email) {
|
|
2115
|
+
email = await prompt(chalk3.white("\uC774\uBA54\uC77C: "));
|
|
2116
|
+
}
|
|
2117
|
+
if (!password) {
|
|
2118
|
+
password = await prompt(chalk3.white("\uBE44\uBC00\uBC88\uD638: "), true);
|
|
2119
|
+
}
|
|
2120
|
+
if (!email || !password) {
|
|
2121
|
+
printError("\uC774\uBA54\uC77C\uACFC \uBE44\uBC00\uBC88\uD638\uB97C \uBAA8\uB450 \uC785\uB825\uD558\uC138\uC694");
|
|
2122
|
+
process.exit(1);
|
|
2123
|
+
}
|
|
2124
|
+
try {
|
|
2125
|
+
const result = await apiLogin(email, password);
|
|
2126
|
+
if (result.success && result.access_token) {
|
|
2127
|
+
setAuth({
|
|
2128
|
+
accessToken: result.access_token,
|
|
2129
|
+
refreshToken: result.refresh_token ?? "",
|
|
2130
|
+
userId: result.user_id ?? "",
|
|
2131
|
+
username: result.username ?? "",
|
|
2132
|
+
isAdmin: false,
|
|
2133
|
+
expiresAt: null
|
|
2134
|
+
});
|
|
2135
|
+
console.log();
|
|
2136
|
+
printSuccess(`\uB85C\uADF8\uC778 \uC131\uACF5! ${chalk3.bold(result.username ?? email)}`);
|
|
2137
|
+
} else {
|
|
2138
|
+
printError(result.message || "\uB85C\uADF8\uC778 \uC2E4\uD328");
|
|
2139
|
+
process.exit(1);
|
|
2140
|
+
}
|
|
2141
|
+
} catch (err) {
|
|
2142
|
+
const msg = err?.response?.data?.message ?? err?.response?.data?.detail ?? err.message;
|
|
2143
|
+
printError(`\uB85C\uADF8\uC778 \uC2E4\uD328: ${msg}`);
|
|
2144
|
+
process.exit(1);
|
|
2145
|
+
}
|
|
2146
|
+
});
|
|
2147
|
+
program2.command("logout").description("\uB85C\uADF8\uC544\uC6C3").action(async () => {
|
|
2148
|
+
const { clearAuth: clearAuth2 } = await Promise.resolve().then(() => (init_store(), store_exports));
|
|
2149
|
+
clearAuth2();
|
|
2150
|
+
printSuccess("\uB85C\uADF8\uC544\uC6C3 \uC644\uB8CC");
|
|
2151
|
+
});
|
|
2152
|
+
program2.command("whoami").description("\uD604\uC7AC \uB85C\uADF8\uC778\uB41C \uC0AC\uC6A9\uC790 \uC815\uBCF4").action(async () => {
|
|
2153
|
+
const auth = getAuth();
|
|
2154
|
+
if (!auth) {
|
|
2155
|
+
printError("\uB85C\uADF8\uC778\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. xgen login \uC2E4\uD589\uD558\uC138\uC694");
|
|
2156
|
+
process.exit(1);
|
|
2157
|
+
}
|
|
2158
|
+
const server = requireServer();
|
|
2159
|
+
console.log(chalk3.bold("\n\uD604\uC7AC \uC0AC\uC6A9\uC790"));
|
|
2160
|
+
console.log(chalk3.gray("\u2500".repeat(30)));
|
|
2161
|
+
console.log(` ${chalk3.gray("\uC11C\uBC84:")} ${server}`);
|
|
2162
|
+
console.log(` ${chalk3.gray("\uC0AC\uC6A9\uC790:")} ${chalk3.bold(auth.username)}`);
|
|
2163
|
+
console.log(` ${chalk3.gray("User ID:")} ${auth.userId}`);
|
|
2164
|
+
try {
|
|
2165
|
+
const { apiValidate: apiValidate2 } = await Promise.resolve().then(() => (init_auth(), auth_exports));
|
|
2166
|
+
const result = await apiValidate2(auth.accessToken);
|
|
2167
|
+
if (result.valid) {
|
|
2168
|
+
console.log(` ${chalk3.gray("\uC0C1\uD0DC:")} ${chalk3.green("\uD65C\uC131")}`);
|
|
2169
|
+
if (result.is_admin) {
|
|
2170
|
+
console.log(` ${chalk3.gray("\uAD8C\uD55C:")} ${chalk3.yellow("\uAD00\uB9AC\uC790")}`);
|
|
2171
|
+
}
|
|
2172
|
+
if (result.user_type) {
|
|
2173
|
+
console.log(` ${chalk3.gray("\uC720\uD615:")} ${result.user_type}`);
|
|
2174
|
+
}
|
|
2175
|
+
} else {
|
|
2176
|
+
console.log(` ${chalk3.gray("\uC0C1\uD0DC:")} ${chalk3.red("\uD1A0\uD070 \uB9CC\uB8CC")}`);
|
|
2177
|
+
}
|
|
2178
|
+
} catch {
|
|
2179
|
+
console.log(` ${chalk3.gray("\uC0C1\uD0DC:")} ${chalk3.yellow("\uAC80\uC99D \uBD88\uAC00 (\uC11C\uBC84 \uC5F0\uACB0 \uC2E4\uD328)")}`);
|
|
2180
|
+
}
|
|
2181
|
+
console.log();
|
|
2182
|
+
});
|
|
2183
|
+
}
|
|
2184
|
+
|
|
2185
|
+
// src/commands/workflow/index.ts
|
|
2186
|
+
init_list();
|
|
2187
|
+
|
|
2188
|
+
// src/commands/workflow/info.ts
|
|
2189
|
+
init_store();
|
|
2190
|
+
init_workflow();
|
|
2191
|
+
init_format();
|
|
2192
|
+
import chalk5 from "chalk";
|
|
2193
|
+
async function workflowInfo(workflowId) {
|
|
2194
|
+
requireAuth();
|
|
2195
|
+
try {
|
|
2196
|
+
const detail = await getWorkflowDetail(workflowId);
|
|
2197
|
+
printHeader(`\uC6CC\uD06C\uD50C\uB85C\uC6B0: ${detail.workflow_name ?? workflowId}`);
|
|
2198
|
+
console.log();
|
|
2199
|
+
printKeyValue("ID", detail.id);
|
|
2200
|
+
printKeyValue("\uC774\uB984", detail.workflow_name);
|
|
2201
|
+
printKeyValue("\uC124\uBA85", detail.description ?? "(\uC5C6\uC74C)");
|
|
2202
|
+
if (detail.nodes && Array.isArray(detail.nodes)) {
|
|
2203
|
+
console.log();
|
|
2204
|
+
console.log(chalk5.bold(" \uB178\uB4DC \uAD6C\uC131:"));
|
|
2205
|
+
for (const node of detail.nodes) {
|
|
2206
|
+
const label = node.data?.label ?? node.id;
|
|
2207
|
+
const type = node.data?.type ?? "unknown";
|
|
2208
|
+
console.log(` ${chalk5.cyan("\u2022")} ${label} ${chalk5.gray(`(${type})`)}`);
|
|
2209
|
+
}
|
|
2210
|
+
}
|
|
2211
|
+
if (detail.parameters && Object.keys(detail.parameters).length > 0) {
|
|
2212
|
+
console.log();
|
|
2213
|
+
console.log(chalk5.bold(" \uD30C\uB77C\uBBF8\uD130:"));
|
|
2214
|
+
for (const [key, val] of Object.entries(detail.parameters)) {
|
|
2215
|
+
console.log(` ${chalk5.gray(key)}: ${JSON.stringify(val)}`);
|
|
2216
|
+
}
|
|
2217
|
+
}
|
|
2218
|
+
console.log();
|
|
2219
|
+
} catch (err) {
|
|
2220
|
+
const msg = err.message;
|
|
2221
|
+
printError(`\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uC870\uD68C \uC2E4\uD328: ${msg}`);
|
|
2222
|
+
process.exit(1);
|
|
2223
|
+
}
|
|
2224
|
+
}
|
|
2225
|
+
|
|
2226
|
+
// src/commands/workflow/run.ts
|
|
2227
|
+
init_store();
|
|
2228
|
+
init_workflow();
|
|
2229
|
+
init_sse();
|
|
2230
|
+
init_format();
|
|
2231
|
+
import chalk7 from "chalk";
|
|
2232
|
+
import { randomUUID } from "crypto";
|
|
2233
|
+
|
|
2234
|
+
// src/utils/markdown.ts
|
|
2235
|
+
import chalk6 from "chalk";
|
|
2236
|
+
var CODE_BLOCK_RE = /```(\w*)\n([\s\S]*?)```/g;
|
|
2237
|
+
var INLINE_CODE_RE = /`([^`]+)`/g;
|
|
2238
|
+
var BOLD_RE = /\*\*(.+?)\*\*/g;
|
|
2239
|
+
var HEADING_RE = /^(#{1,3})\s+(.+)$/gm;
|
|
2240
|
+
var LIST_RE = /^(\s*)[-*]\s+(.+)$/gm;
|
|
2241
|
+
var LINK_RE = /\[([^\]]+)\]\(([^)]+)\)/g;
|
|
2242
|
+
function renderMarkdown(text) {
|
|
2243
|
+
let result = text;
|
|
2244
|
+
result = result.replace(CODE_BLOCK_RE, (_match, lang, code) => {
|
|
2245
|
+
const trimmed = code.trimEnd();
|
|
2246
|
+
const header = lang ? chalk6.gray(` \u2500\u2500 ${lang} \u2500\u2500`) : chalk6.gray(" \u2500\u2500 code \u2500\u2500");
|
|
2247
|
+
const lines = trimmed.split("\n").map((l) => chalk6.white(` ${l}`)).join("\n");
|
|
2248
|
+
return `
|
|
2249
|
+
${header}
|
|
2250
|
+
${lines}
|
|
2251
|
+
${chalk6.gray(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500")}
|
|
2252
|
+
`;
|
|
2253
|
+
});
|
|
2254
|
+
result = result.replace(INLINE_CODE_RE, (_m, code) => chalk6.cyan(`\`${code}\``));
|
|
2255
|
+
result = result.replace(BOLD_RE, (_m, text2) => chalk6.bold(text2));
|
|
2256
|
+
result = result.replace(HEADING_RE, (_m, hashes, text2) => {
|
|
2257
|
+
if (hashes.length === 1) return chalk6.bold.underline(text2);
|
|
2258
|
+
if (hashes.length === 2) return chalk6.bold(text2);
|
|
2259
|
+
return chalk6.bold.dim(text2);
|
|
2260
|
+
});
|
|
2261
|
+
result = result.replace(LIST_RE, (_m, indent, text2) => `${indent}${chalk6.cyan("\u2022")} ${text2}`);
|
|
2262
|
+
result = result.replace(LINK_RE, (_m, label, url) => `${chalk6.blue.underline(label)} ${chalk6.gray(`(${url})`)}`);
|
|
2263
|
+
return result;
|
|
2264
|
+
}
|
|
2265
|
+
|
|
2266
|
+
// src/commands/workflow/run.ts
|
|
2267
|
+
async function workflowRun(workflowId, input, opts) {
|
|
2268
|
+
const auth = requireAuth();
|
|
2269
|
+
let workflowName = workflowId;
|
|
2270
|
+
try {
|
|
2271
|
+
const detail = await getWorkflowDetail(workflowId);
|
|
2272
|
+
workflowName = detail.workflow_name ?? workflowId;
|
|
2273
|
+
} catch {
|
|
2274
|
+
}
|
|
2275
|
+
if (!input) {
|
|
2276
|
+
if (opts.interactive || !process.stdin.isTTY) {
|
|
2277
|
+
const { createInterface: createInterface8 } = await import("readline");
|
|
2278
|
+
const rl = createInterface8({ input: process.stdin, output: process.stdout });
|
|
2279
|
+
input = await new Promise((resolve) => {
|
|
2280
|
+
rl.question(chalk7.cyan("\uC785\uB825> "), (answer) => {
|
|
2281
|
+
rl.close();
|
|
2282
|
+
resolve(answer.trim());
|
|
2283
|
+
});
|
|
2284
|
+
});
|
|
2285
|
+
} else {
|
|
2286
|
+
printError("\uC785\uB825\uAC12\uC774 \uD544\uC694\uD569\uB2C8\uB2E4. \uC0AC\uC6A9\uBC95:");
|
|
2287
|
+
console.log(' xgen workflow run <id> "\uC785\uB825 \uD14D\uC2A4\uFFFD\uFFFD\uFFFD"');
|
|
2288
|
+
console.log(" xgen workflow run -i <id>");
|
|
2289
|
+
process.exit(1);
|
|
2290
|
+
}
|
|
2291
|
+
}
|
|
2292
|
+
if (!input) {
|
|
2293
|
+
printError("\uC785\uB825\uAC12\uC774 \uBE44\uC5B4\uC788\uC2B5\uB2C8\uB2E4");
|
|
2294
|
+
process.exit(1);
|
|
1781
2295
|
}
|
|
1782
|
-
|
|
2296
|
+
const interactionId = `cli_${randomUUID().slice(0, 8)}`;
|
|
2297
|
+
printHeader(`\uC2E4\uD589: ${workflowName}`);
|
|
2298
|
+
printInfo(`\uC785\uB825: ${input}`);
|
|
1783
2299
|
console.log();
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
}
|
|
1811
|
-
console.log();
|
|
1812
|
-
continue;
|
|
1813
|
-
}
|
|
1814
|
-
if (input === "/provider") {
|
|
1815
|
-
console.log(chalk11.gray(`\uD604\uC7AC: ${provider.name} (${provider.model})
|
|
2300
|
+
try {
|
|
2301
|
+
const stream = await executeWorkflowStream({
|
|
2302
|
+
workflow_id: workflowId,
|
|
2303
|
+
workflow_name: workflowName,
|
|
2304
|
+
input_data: input,
|
|
2305
|
+
interaction_id: interactionId
|
|
2306
|
+
});
|
|
2307
|
+
let hasOutput = false;
|
|
2308
|
+
let fullResponse = "";
|
|
2309
|
+
await parseSSEStream(
|
|
2310
|
+
stream,
|
|
2311
|
+
(event) => {
|
|
2312
|
+
switch (event.type) {
|
|
2313
|
+
case "token":
|
|
2314
|
+
if (event.content) {
|
|
2315
|
+
if (!hasOutput) {
|
|
2316
|
+
hasOutput = true;
|
|
2317
|
+
console.log();
|
|
2318
|
+
}
|
|
2319
|
+
process.stdout.write(event.content);
|
|
2320
|
+
fullResponse += event.content;
|
|
2321
|
+
}
|
|
2322
|
+
break;
|
|
2323
|
+
case "log":
|
|
2324
|
+
if (opts.logs && event.content) {
|
|
2325
|
+
process.stderr.write(chalk7.gray(`[LOG] ${event.content}
|
|
1816
2326
|
`));
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
} catch (err) {
|
|
1833
|
-
console.log(chalk11.red(`
|
|
1834
|
-
\uC624\uB958: ${err.message}
|
|
2327
|
+
}
|
|
2328
|
+
break;
|
|
2329
|
+
case "node_status":
|
|
2330
|
+
if (opts.logs) {
|
|
2331
|
+
const nodeName = event.node_name ?? event.node_id ?? "?";
|
|
2332
|
+
const status = event.status ?? "?";
|
|
2333
|
+
process.stderr.write(
|
|
2334
|
+
chalk7.gray(`[\uB178\uB4DC] ${nodeName}: ${status}
|
|
2335
|
+
`)
|
|
2336
|
+
);
|
|
2337
|
+
}
|
|
2338
|
+
break;
|
|
2339
|
+
case "tool":
|
|
2340
|
+
if (opts.logs) {
|
|
2341
|
+
process.stderr.write(chalk7.gray(`[\uB3C4\uAD6C] ${JSON.stringify(event.data)}
|
|
1835
2342
|
`));
|
|
1836
|
-
|
|
2343
|
+
}
|
|
2344
|
+
break;
|
|
2345
|
+
case "complete":
|
|
2346
|
+
break;
|
|
2347
|
+
case "error":
|
|
2348
|
+
console.log();
|
|
2349
|
+
printError(event.error ?? event.content ?? "\uC54C \uC218 \uC5C6\uB294 \uC624\uB958");
|
|
2350
|
+
break;
|
|
2351
|
+
default:
|
|
2352
|
+
if (event.content) {
|
|
2353
|
+
if (!hasOutput) {
|
|
2354
|
+
process.stdout.write(chalk7.green("\uC751\uB2F5: "));
|
|
2355
|
+
hasOutput = true;
|
|
2356
|
+
}
|
|
2357
|
+
process.stdout.write(event.content);
|
|
2358
|
+
}
|
|
2359
|
+
}
|
|
2360
|
+
},
|
|
2361
|
+
() => {
|
|
2362
|
+
if (hasOutput) {
|
|
2363
|
+
console.log();
|
|
2364
|
+
if (fullResponse.includes("```") || fullResponse.includes("**")) {
|
|
2365
|
+
console.log(chalk7.gray("\u2500".repeat(40)));
|
|
2366
|
+
console.log(renderMarkdown(fullResponse));
|
|
2367
|
+
}
|
|
2368
|
+
}
|
|
2369
|
+
console.log();
|
|
2370
|
+
console.log(chalk7.gray(`\uC138\uC158: ${interactionId}`));
|
|
2371
|
+
},
|
|
2372
|
+
(err) => {
|
|
2373
|
+
console.log();
|
|
2374
|
+
printError(`\uC2A4\uD2B8\uB9AC\uBC0D \uC624\uB958: ${err.message}`);
|
|
2375
|
+
}
|
|
2376
|
+
);
|
|
2377
|
+
} catch (err) {
|
|
2378
|
+
const msg = err?.response?.data?.detail ?? err.message;
|
|
2379
|
+
printError(`\uC2E4\uD589 \uC2E4\uD328: ${msg}`);
|
|
2380
|
+
process.exit(1);
|
|
1837
2381
|
}
|
|
1838
2382
|
}
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
2383
|
+
|
|
2384
|
+
// src/commands/workflow/history.ts
|
|
2385
|
+
init_store();
|
|
2386
|
+
init_workflow();
|
|
2387
|
+
init_format();
|
|
2388
|
+
import chalk8 from "chalk";
|
|
2389
|
+
async function workflowHistory(workflowId, opts = {}) {
|
|
2390
|
+
requireAuth();
|
|
2391
|
+
const limit = opts.limit ?? 20;
|
|
2392
|
+
try {
|
|
2393
|
+
const logs = await getIOLogs(workflowId, limit);
|
|
2394
|
+
if (!logs || logs.length === 0) {
|
|
2395
|
+
console.log(chalk8.yellow("\n\uC2E4\uD589 \uC774\uB825\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.\n"));
|
|
1852
2396
|
return;
|
|
1853
2397
|
}
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
})
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
args = {};
|
|
1869
|
-
}
|
|
1870
|
-
console.log(chalk11.gray(` \u2699 ${tc.name}(`), chalk11.dim(summarizeArgs(args)), chalk11.gray(")"));
|
|
1871
|
-
let toolResult;
|
|
1872
|
-
if (mcpManager?.isMcpTool(tc.name)) {
|
|
1873
|
-
toolResult = await mcpManager.callTool(tc.name, args);
|
|
1874
|
-
} else {
|
|
1875
|
-
toolResult = await executeTool(tc.name, args);
|
|
2398
|
+
printHeader(`\uC2E4\uD589 \uC774\uB825 (\uCD5C\uADFC ${logs.length}\uAC74)`);
|
|
2399
|
+
console.log();
|
|
2400
|
+
for (const log of logs) {
|
|
2401
|
+
console.log(
|
|
2402
|
+
` ${chalk8.gray(formatDate(log.created_at))} ${chalk8.cyan(log.interaction_id)}`
|
|
2403
|
+
);
|
|
2404
|
+
console.log(` ${chalk8.white("\uC785\uB825:")} ${truncate(log.input_data, 60)}`);
|
|
2405
|
+
console.log(
|
|
2406
|
+
` ${chalk8.green("\uCD9C\uB825:")} ${truncate(log.output_data, 60)}`
|
|
2407
|
+
);
|
|
2408
|
+
if (log.execution_time) {
|
|
2409
|
+
console.log(
|
|
2410
|
+
` ${chalk8.gray("\uC2DC\uAC04:")} ${(log.execution_time / 1e3).toFixed(1)}s`
|
|
2411
|
+
);
|
|
1876
2412
|
}
|
|
1877
|
-
|
|
1878
|
-
messages.push({
|
|
1879
|
-
role: "tool",
|
|
1880
|
-
tool_call_id: tc.id,
|
|
1881
|
-
content: truncated
|
|
1882
|
-
});
|
|
2413
|
+
console.log();
|
|
1883
2414
|
}
|
|
2415
|
+
} catch (err) {
|
|
2416
|
+
const msg = err.message;
|
|
2417
|
+
printError(`\uC774\uB825 \uC870\uD68C \uC2E4\uD328: ${msg}`);
|
|
2418
|
+
process.exit(1);
|
|
1884
2419
|
}
|
|
1885
|
-
console.log(chalk11.yellow("\n\uCD5C\uB300 \uBC18\uBCF5 \uD69F\uC218\uC5D0 \uB3C4\uB2EC\uD588\uC2B5\uB2C8\uB2E4.\n"));
|
|
1886
|
-
}
|
|
1887
|
-
function summarizeArgs(args) {
|
|
1888
|
-
const parts = [];
|
|
1889
|
-
for (const [k, v] of Object.entries(args)) {
|
|
1890
|
-
const s = String(v);
|
|
1891
|
-
parts.push(`${k}: ${s.length > 40 ? s.slice(0, 40) + "..." : s}`);
|
|
1892
|
-
}
|
|
1893
|
-
return parts.join(", ");
|
|
1894
2420
|
}
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
2421
|
+
|
|
2422
|
+
// src/commands/workflow/index.ts
|
|
2423
|
+
function registerWorkflowCommand(program2) {
|
|
2424
|
+
const wf = program2.command("workflow").alias("wf").description("\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uAD00\uB9AC \uBC0F \uC2E4\uD589");
|
|
2425
|
+
wf.command("list").alias("ls").description("\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uBAA9\uB85D \uC870\uD68C").option("-d, --detail", "\uC0C1\uC138 \uC815\uBCF4 \uD3EC\uD568").action((opts) => workflowList(opts));
|
|
2426
|
+
wf.command("info <workflow-id>").description("\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uC0C1\uC138 \uC815\uBCF4").action((id) => workflowInfo(id));
|
|
2427
|
+
wf.command("run <workflow-id> [input]").description("\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uC2E4\uD589").option("-i, --interactive", "\uC778\uD130\uB799\uD2F0\uBE0C \uBAA8\uB4DC (\uC785\uB825 \uD504\uB86C\uD504\uD2B8)").option("-l, --logs", "\uB514\uBC84\uADF8 \uB85C\uADF8 \uD45C\uC2DC").action((id, input, opts) => workflowRun(id, input, opts));
|
|
2428
|
+
wf.command("history [workflow-id]").description("\uC2E4\uD589 \uC774\uB825 \uC870\uD68C").option("-n, --limit <number>", "\uC870\uD68C \uAC74\uC218", "20").action((id, opts) => workflowHistory(id, { limit: parseInt(opts.limit) }));
|
|
1899
2429
|
}
|
|
1900
2430
|
|
|
2431
|
+
// src/index.ts
|
|
2432
|
+
init_chat();
|
|
2433
|
+
init_provider();
|
|
2434
|
+
init_agent();
|
|
2435
|
+
|
|
1901
2436
|
// src/commands/doc.ts
|
|
1902
2437
|
init_store();
|
|
1903
|
-
import
|
|
2438
|
+
import chalk13 from "chalk";
|
|
1904
2439
|
|
|
1905
2440
|
// src/api/document.ts
|
|
2441
|
+
init_client();
|
|
1906
2442
|
import { createReadStream, statSync } from "fs";
|
|
1907
2443
|
import { basename } from "path";
|
|
1908
2444
|
async function listDocuments(collectionId) {
|
|
@@ -1935,6 +2471,7 @@ async function getDocumentInfo(docId) {
|
|
|
1935
2471
|
}
|
|
1936
2472
|
|
|
1937
2473
|
// src/commands/doc.ts
|
|
2474
|
+
init_format();
|
|
1938
2475
|
function registerDocCommand(program2) {
|
|
1939
2476
|
const doc = program2.command("doc").description("\uBB38\uC11C \uAD00\uB9AC");
|
|
1940
2477
|
doc.command("list").alias("ls").description("\uBB38\uC11C \uBAA9\uB85D \uC870\uD68C").option("-c, --collection <id>", "\uCEEC\uB809\uC158 ID").action(async (opts) => {
|
|
@@ -1942,7 +2479,7 @@ function registerDocCommand(program2) {
|
|
|
1942
2479
|
try {
|
|
1943
2480
|
const docs = await listDocuments(opts.collection);
|
|
1944
2481
|
if (!docs.length) {
|
|
1945
|
-
console.log(
|
|
2482
|
+
console.log(chalk13.yellow("\n\uBB38\uC11C\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.\n"));
|
|
1946
2483
|
return;
|
|
1947
2484
|
}
|
|
1948
2485
|
printHeader(`\uBB38\uC11C \uBAA9\uB85D (${docs.length}\uAC1C)`);
|
|
@@ -1966,10 +2503,10 @@ function registerDocCommand(program2) {
|
|
|
1966
2503
|
doc.command("upload <file>").description("\uBB38\uC11C \uC5C5\uB85C\uB4DC").option("-c, --collection <id>", "\uCEEC\uB809\uC158 ID").option("-n, --name <name>", "\uD30C\uC77C\uBA85").action(async (file, opts) => {
|
|
1967
2504
|
requireAuth();
|
|
1968
2505
|
try {
|
|
1969
|
-
console.log(
|
|
2506
|
+
console.log(chalk13.gray(`\uC5C5\uB85C\uB4DC \uC911: ${file}`));
|
|
1970
2507
|
const result = await uploadDocument(file, opts.collection, opts.name);
|
|
1971
|
-
console.log(
|
|
1972
|
-
console.log(
|
|
2508
|
+
console.log(chalk13.green("\u2713 \uC5C5\uB85C\uB4DC \uC644\uB8CC"));
|
|
2509
|
+
console.log(chalk13.gray(JSON.stringify(result, null, 2)));
|
|
1973
2510
|
} catch (err) {
|
|
1974
2511
|
printError(`\uC5C5\uB85C\uB4DC \uC2E4\uD328: ${err.message}`);
|
|
1975
2512
|
}
|
|
@@ -1979,7 +2516,7 @@ function registerDocCommand(program2) {
|
|
|
1979
2516
|
try {
|
|
1980
2517
|
const d = await getDocumentInfo(id);
|
|
1981
2518
|
printHeader("\uBB38\uC11C \uC815\uBCF4");
|
|
1982
|
-
console.log(
|
|
2519
|
+
console.log(chalk13.gray(JSON.stringify(d, null, 2)));
|
|
1983
2520
|
} catch (err) {
|
|
1984
2521
|
printError(`\uC870\uD68C \uC2E4\uD328: ${err.message}`);
|
|
1985
2522
|
}
|
|
@@ -1988,10 +2525,11 @@ function registerDocCommand(program2) {
|
|
|
1988
2525
|
|
|
1989
2526
|
// src/commands/ontology.ts
|
|
1990
2527
|
init_store();
|
|
1991
|
-
import
|
|
1992
|
-
import { createInterface as
|
|
2528
|
+
import chalk14 from "chalk";
|
|
2529
|
+
import { createInterface as createInterface7 } from "readline";
|
|
1993
2530
|
|
|
1994
2531
|
// src/api/ontology.ts
|
|
2532
|
+
init_client();
|
|
1995
2533
|
async function queryGraphRAG(query, graphId, opts) {
|
|
1996
2534
|
const client2 = getClient();
|
|
1997
2535
|
const res = await client2.post("/api/graph-rag", {
|
|
@@ -2018,25 +2556,26 @@ async function getGraphStats(graphId) {
|
|
|
2018
2556
|
}
|
|
2019
2557
|
|
|
2020
2558
|
// src/commands/ontology.ts
|
|
2559
|
+
init_format();
|
|
2021
2560
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
2022
2561
|
function registerOntologyCommand(program2) {
|
|
2023
2562
|
const ont = program2.command("ontology").alias("ont").description("\uC628\uD1A8\uB85C\uC9C0 GraphRAG \uC9C8\uC758");
|
|
2024
2563
|
ont.command("query <question>").alias("q").description("GraphRAG \uC6D0\uC0F7 \uC9C8\uC758").option("-g, --graph <id>", "\uADF8\uB798\uD504 ID").option("--no-scs", "SCS \uCEE8\uD14D\uC2A4\uD2B8 \uBE44\uD65C\uC131\uD654").action(async (question, opts) => {
|
|
2025
2564
|
requireAuth();
|
|
2026
2565
|
try {
|
|
2027
|
-
console.log(
|
|
2566
|
+
console.log(chalk14.gray("\n\uC9C8\uC758 \uC911...\n"));
|
|
2028
2567
|
const result = await queryGraphRAG(question, opts.graph, { scs: opts.scs });
|
|
2029
2568
|
if (result.answer) {
|
|
2030
|
-
console.log(
|
|
2569
|
+
console.log(chalk14.bold("\uB2F5\uBCC0:"));
|
|
2031
2570
|
console.log(result.answer);
|
|
2032
2571
|
}
|
|
2033
2572
|
if (result.sources?.length) {
|
|
2034
|
-
console.log(
|
|
2035
|
-
result.sources.forEach((s) => console.log(
|
|
2573
|
+
console.log(chalk14.bold("\n\uCD9C\uCC98:"));
|
|
2574
|
+
result.sources.forEach((s) => console.log(chalk14.gray(` - ${s}`)));
|
|
2036
2575
|
}
|
|
2037
2576
|
if (result.triples_used?.length) {
|
|
2038
|
-
console.log(
|
|
2039
|
-
result.triples_used.forEach((t) => console.log(
|
|
2577
|
+
console.log(chalk14.bold("\n\uC0AC\uC6A9\uB41C \uD2B8\uB9AC\uD50C:"));
|
|
2578
|
+
result.triples_used.forEach((t) => console.log(chalk14.dim(` ${t}`)));
|
|
2040
2579
|
}
|
|
2041
2580
|
console.log();
|
|
2042
2581
|
} catch (err) {
|
|
@@ -2047,9 +2586,9 @@ function registerOntologyCommand(program2) {
|
|
|
2047
2586
|
requireAuth();
|
|
2048
2587
|
const sessionId = randomUUID3();
|
|
2049
2588
|
printHeader("Ontology Chat");
|
|
2050
|
-
console.log(
|
|
2051
|
-
const rl =
|
|
2052
|
-
const ask = () => new Promise((resolve) => rl.question(
|
|
2589
|
+
console.log(chalk14.gray("\uBA40\uD2F0\uD134 GraphRAG \uB300\uD654. exit\uB85C \uC885\uB8CC.\n"));
|
|
2590
|
+
const rl = createInterface7({ input: process.stdin, output: process.stdout });
|
|
2591
|
+
const ask = () => new Promise((resolve) => rl.question(chalk14.green("\u276F "), (a) => resolve(a.trim())));
|
|
2053
2592
|
while (true) {
|
|
2054
2593
|
const input = await ask();
|
|
2055
2594
|
if (!input) continue;
|
|
@@ -2063,7 +2602,7 @@ function registerOntologyCommand(program2) {
|
|
|
2063
2602
|
${result.answer}
|
|
2064
2603
|
`);
|
|
2065
2604
|
} catch (err) {
|
|
2066
|
-
console.log(
|
|
2605
|
+
console.log(chalk14.red(`\uC624\uB958: ${err.message}
|
|
2067
2606
|
`));
|
|
2068
2607
|
}
|
|
2069
2608
|
}
|
|
@@ -2073,7 +2612,7 @@ ${result.answer}
|
|
|
2073
2612
|
try {
|
|
2074
2613
|
const stats = await getGraphStats(graphId);
|
|
2075
2614
|
printHeader("\uADF8\uB798\uD504 \uD1B5\uACC4");
|
|
2076
|
-
console.log(
|
|
2615
|
+
console.log(chalk14.gray(JSON.stringify(stats, null, 2)));
|
|
2077
2616
|
console.log();
|
|
2078
2617
|
} catch (err) {
|
|
2079
2618
|
printError(`\uD1B5\uACC4 \uC870\uD68C \uC2E4\uD328: ${err.message}`);
|
|
@@ -2082,44 +2621,44 @@ ${result.answer}
|
|
|
2082
2621
|
}
|
|
2083
2622
|
|
|
2084
2623
|
// src/index.ts
|
|
2085
|
-
|
|
2624
|
+
init_home();
|
|
2086
2625
|
var VERSION = "0.3.0";
|
|
2087
|
-
var LOGO =
|
|
2626
|
+
var LOGO = chalk15.cyan(`
|
|
2088
2627
|
\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588 \u2588\u2588
|
|
2089
2628
|
\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588 \u2588\u2588
|
|
2090
2629
|
\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588
|
|
2091
2630
|
\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588
|
|
2092
2631
|
\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588
|
|
2093
|
-
`) +
|
|
2632
|
+
`) + chalk15.white.bold(`
|
|
2094
2633
|
\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588 \u2588\u2588
|
|
2095
2634
|
\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588 \u2588\u2588
|
|
2096
2635
|
\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588
|
|
2097
2636
|
\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588
|
|
2098
2637
|
\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588
|
|
2099
|
-
`) +
|
|
2638
|
+
`) + chalk15.gray(` v${VERSION}
|
|
2100
2639
|
`);
|
|
2101
2640
|
var BANNER = LOGO;
|
|
2102
2641
|
var program = new Command();
|
|
2103
2642
|
program.name("xgen").description("OPEN XGEN \u2014 AI Coding Agent + XGEN Platform CLI").version(VERSION).addHelpText("before", BANNER).addHelpText(
|
|
2104
2643
|
"after",
|
|
2105
2644
|
`
|
|
2106
|
-
${
|
|
2107
|
-
${
|
|
2108
|
-
${
|
|
2109
|
-
${
|
|
2110
|
-
${
|
|
2645
|
+
${chalk15.bold("\uC2DC\uC791\uD558\uAE30:")}
|
|
2646
|
+
${chalk15.cyan("xgen provider add")} AI \uD504\uB85C\uBC14\uC774\uB354 \uC124\uC815
|
|
2647
|
+
${chalk15.cyan("xgen agent")} AI \uCF54\uB529 \uC5D0\uC774\uC804\uD2B8
|
|
2648
|
+
${chalk15.cyan("xgen config set-server")} <url> XGEN \uC11C\uBC84 \uC5F0\uACB0
|
|
2649
|
+
${chalk15.cyan("xgen login")} \uC11C\uBC84 \uB85C\uADF8\uC778
|
|
2111
2650
|
|
|
2112
|
-
${
|
|
2113
|
-
${
|
|
2114
|
-
${
|
|
2115
|
-
${
|
|
2651
|
+
${chalk15.bold("AI \uC5D0\uC774\uC804\uD2B8:")}
|
|
2652
|
+
${chalk15.cyan("xgen agent")} \uCF54\uB529 \uC5D0\uC774\uC804\uD2B8 (\uD30C\uC77C, \uD130\uBBF8\uB110, \uAC80\uC0C9)
|
|
2653
|
+
${chalk15.cyan("xgen provider ls")} \uD504\uB85C\uBC14\uC774\uB354 \uBAA9\uB85D
|
|
2654
|
+
${chalk15.cyan("xgen provider add")} \uD504\uB85C\uBC14\uC774\uB354 \uCD94\uAC00
|
|
2116
2655
|
|
|
2117
|
-
${
|
|
2118
|
-
${
|
|
2119
|
-
${
|
|
2120
|
-
${
|
|
2121
|
-
${
|
|
2122
|
-
${
|
|
2656
|
+
${chalk15.bold("XGEN \uD50C\uB7AB\uD3FC:")}
|
|
2657
|
+
${chalk15.cyan("xgen chat")} \uC6CC\uD06C\uD50C\uB85C\uC6B0 \uB300\uD654
|
|
2658
|
+
${chalk15.cyan("xgen wf ls")} \uC6CC\uD06C\uD50C\uB85C\uC6B0 \uBAA9\uB85D
|
|
2659
|
+
${chalk15.cyan("xgen wf run")} <id> "\uC9C8\uBB38" \uC6CC\uD06C\uD50C\uB85C\uC6B0 \uC2E4\uD589
|
|
2660
|
+
${chalk15.cyan("xgen doc ls")} \uBB38\uC11C \uBAA9\uB85D
|
|
2661
|
+
${chalk15.cyan("xgen ont query")} "\uC9C8\uBB38" \uC628\uD1A8\uB85C\uC9C0 \uC9C8\uC758
|
|
2123
2662
|
`
|
|
2124
2663
|
);
|
|
2125
2664
|
registerConfigCommand(program);
|
|
@@ -2131,30 +2670,10 @@ registerAgentCommand(program);
|
|
|
2131
2670
|
registerDocCommand(program);
|
|
2132
2671
|
registerOntologyCommand(program);
|
|
2133
2672
|
if (process.argv.length <= 2) {
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
agentRepl().catch((err) => {
|
|
2139
|
-
console.error(chalk14.red(`\uC624\uB958: ${err.message}`));
|
|
2140
|
-
process.exit(1);
|
|
2141
|
-
});
|
|
2142
|
-
} else if (auth && server) {
|
|
2143
|
-
chat().catch((err) => {
|
|
2144
|
-
console.error(chalk14.red(`\uC624\uB958: ${err.message}`));
|
|
2145
|
-
process.exit(1);
|
|
2146
|
-
});
|
|
2147
|
-
} else {
|
|
2148
|
-
console.log(BANNER);
|
|
2149
|
-
console.log(chalk14.yellow(" \uC124\uC815\uC774 \uD544\uC694\uD569\uB2C8\uB2E4.\n"));
|
|
2150
|
-
console.log(chalk14.bold(" AI \uC5D0\uC774\uC804\uD2B8:"));
|
|
2151
|
-
console.log(` ${chalk14.cyan("xgen provider add")} \uD504\uB85C\uBC14\uC774\uB354 \uCD94\uAC00
|
|
2152
|
-
`);
|
|
2153
|
-
console.log(chalk14.bold(" XGEN \uD50C\uB7AB\uD3FC:"));
|
|
2154
|
-
console.log(` ${chalk14.cyan("xgen config set-server")} <url> \uC11C\uBC84 \uC124\uC815`);
|
|
2155
|
-
console.log(` ${chalk14.cyan("xgen login")} \uB85C\uADF8\uC778
|
|
2156
|
-
`);
|
|
2157
|
-
}
|
|
2673
|
+
homeMenu().catch((err) => {
|
|
2674
|
+
console.error(chalk15.red(`\uC624\uB958: ${err.message}`));
|
|
2675
|
+
process.exit(1);
|
|
2676
|
+
});
|
|
2158
2677
|
} else {
|
|
2159
2678
|
program.parse();
|
|
2160
2679
|
}
|