openxgen 0.6.1 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1192 -1083
- package/dist/index.js.map +1 -1
- package/package.json +10 -2
package/dist/index.js
CHANGED
|
@@ -426,293 +426,6 @@ var init_workflow = __esm({
|
|
|
426
426
|
}
|
|
427
427
|
});
|
|
428
428
|
|
|
429
|
-
// src/utils/sse.ts
|
|
430
|
-
async function parseSSEStream(stream, onEvent, onDone, onError) {
|
|
431
|
-
let buffer = "";
|
|
432
|
-
return new Promise((resolve, reject) => {
|
|
433
|
-
stream.on("data", (chunk) => {
|
|
434
|
-
buffer += chunk.toString();
|
|
435
|
-
const parts = buffer.split("\n\n");
|
|
436
|
-
buffer = parts.pop() ?? "";
|
|
437
|
-
for (const part of parts) {
|
|
438
|
-
const lines = part.split("\n");
|
|
439
|
-
let data = "";
|
|
440
|
-
for (const line of lines) {
|
|
441
|
-
if (line.startsWith("data: ")) {
|
|
442
|
-
data += line.slice(6);
|
|
443
|
-
} else if (line.startsWith("data:")) {
|
|
444
|
-
data += line.slice(5);
|
|
445
|
-
}
|
|
446
|
-
}
|
|
447
|
-
if (!data) continue;
|
|
448
|
-
try {
|
|
449
|
-
const event = JSON.parse(data);
|
|
450
|
-
onEvent(event);
|
|
451
|
-
} catch {
|
|
452
|
-
onEvent({ type: "token", content: data });
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
});
|
|
456
|
-
stream.on("end", () => {
|
|
457
|
-
if (buffer.trim()) {
|
|
458
|
-
const lines = buffer.split("\n");
|
|
459
|
-
for (const line of lines) {
|
|
460
|
-
if (line.startsWith("data: ")) {
|
|
461
|
-
try {
|
|
462
|
-
const event = JSON.parse(line.slice(6));
|
|
463
|
-
onEvent(event);
|
|
464
|
-
} catch {
|
|
465
|
-
onEvent({ type: "token", content: line.slice(6) });
|
|
466
|
-
}
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
}
|
|
470
|
-
onDone?.();
|
|
471
|
-
resolve();
|
|
472
|
-
});
|
|
473
|
-
stream.on("error", (err) => {
|
|
474
|
-
onError?.(err);
|
|
475
|
-
reject(err);
|
|
476
|
-
});
|
|
477
|
-
});
|
|
478
|
-
}
|
|
479
|
-
var init_sse = __esm({
|
|
480
|
-
"src/utils/sse.ts"() {
|
|
481
|
-
"use strict";
|
|
482
|
-
}
|
|
483
|
-
});
|
|
484
|
-
|
|
485
|
-
// src/commands/chat.ts
|
|
486
|
-
import chalk9 from "chalk";
|
|
487
|
-
import { createInterface as createInterface2 } from "readline";
|
|
488
|
-
import { randomUUID as randomUUID2 } from "crypto";
|
|
489
|
-
function printHelp() {
|
|
490
|
-
console.log(`
|
|
491
|
-
${chalk9.bold("\uC2AC\uB798\uC2DC \uCEE4\uB9E8\uB4DC")}
|
|
492
|
-
${chalk9.cyan("/workflows")} \uC6CC\uD06C\uD50C\uB85C\uC6B0 \uBAA9\uB85D \uBCF4\uAE30 & \uC804\uD658
|
|
493
|
-
${chalk9.cyan("/switch")} \uC6CC\uD06C\uD50C\uB85C\uC6B0 \uBC88\uD638\uB85C \uC804\uD658 (\uC608: /switch 3)
|
|
494
|
-
${chalk9.cyan("/history")} \uD604\uC7AC \uC138\uC158 \uB300\uD654 \uC774\uB825
|
|
495
|
-
${chalk9.cyan("/clear")} \uD654\uBA74 \uC9C0\uC6B0\uAE30
|
|
496
|
-
${chalk9.cyan("/info")} \uD604\uC7AC \uC5F0\uACB0 \uC815\uBCF4
|
|
497
|
-
${chalk9.cyan("/help")} \uC774 \uB3C4\uC6C0\uB9D0
|
|
498
|
-
${chalk9.cyan("/exit")} \uC885\uB8CC (Ctrl+C\uB3C4 \uAC00\uB2A5)
|
|
499
|
-
`);
|
|
500
|
-
}
|
|
501
|
-
async function promptLine(rl, promptStr) {
|
|
502
|
-
return new Promise((resolve) => {
|
|
503
|
-
rl.question(promptStr, (answer) => resolve(answer));
|
|
504
|
-
});
|
|
505
|
-
}
|
|
506
|
-
async function chat(workflowId) {
|
|
507
|
-
const auth = requireAuth();
|
|
508
|
-
const server = getServer();
|
|
509
|
-
let workflows = [];
|
|
510
|
-
try {
|
|
511
|
-
workflows = await listWorkflows();
|
|
512
|
-
} catch {
|
|
513
|
-
printError("\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uBAA9\uB85D\uC744 \uBD88\uB7EC\uC62C \uC218 \uC5C6\uC2B5\uB2C8\uB2E4");
|
|
514
|
-
process.exit(1);
|
|
515
|
-
}
|
|
516
|
-
if (workflows.length === 0) {
|
|
517
|
-
printError("\uC0AC\uC6A9 \uAC00\uB2A5\uD55C \uC6CC\uD06C\uD50C\uB85C\uC6B0\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4");
|
|
518
|
-
process.exit(1);
|
|
519
|
-
}
|
|
520
|
-
let current;
|
|
521
|
-
if (workflowId) {
|
|
522
|
-
const found = workflows.find((w) => w.id === workflowId || w.workflow_name === workflowId);
|
|
523
|
-
current = found ?? { id: workflowId, workflow_name: workflowId };
|
|
524
|
-
} else {
|
|
525
|
-
console.log(CHAT_BANNER);
|
|
526
|
-
console.log(chalk9.gray(` \uC11C\uBC84: ${server} | \uC0AC\uC6A9\uC790: ${auth.username}
|
|
527
|
-
`));
|
|
528
|
-
console.log(chalk9.bold(" \uC6CC\uD06C\uD50C\uB85C\uC6B0 \uC120\uD0DD:\n"));
|
|
529
|
-
workflows.forEach((w, i) => {
|
|
530
|
-
console.log(` ${chalk9.cyan(String(i + 1).padStart(3))} ${w.workflow_name}`);
|
|
531
|
-
});
|
|
532
|
-
console.log();
|
|
533
|
-
const rl2 = createInterface2({ input: process.stdin, output: process.stdout });
|
|
534
|
-
const answer = await promptLine(rl2, chalk9.cyan(" \uBC88\uD638> "));
|
|
535
|
-
rl2.close();
|
|
536
|
-
const idx = parseInt(answer.trim()) - 1;
|
|
537
|
-
if (isNaN(idx) || idx < 0 || idx >= workflows.length) {
|
|
538
|
-
current = workflows[0];
|
|
539
|
-
} else {
|
|
540
|
-
current = workflows[idx];
|
|
541
|
-
}
|
|
542
|
-
}
|
|
543
|
-
const sessionId = randomUUID2().slice(0, 8);
|
|
544
|
-
let turnCount = 0;
|
|
545
|
-
const history = [];
|
|
546
|
-
console.log();
|
|
547
|
-
console.log(chalk9.cyan("\u2500".repeat(42)));
|
|
548
|
-
console.log(chalk9.white.bold(` ${current.workflow_name}`));
|
|
549
|
-
console.log(chalk9.cyan("\u2500".repeat(42)));
|
|
550
|
-
console.log(chalk9.gray(" \uBA54\uC2DC\uC9C0\uB97C \uC785\uB825\uD558\uC138\uC694. /help \uB85C \uB3C4\uC6C0\uB9D0.\n"));
|
|
551
|
-
const rl = createInterface2({
|
|
552
|
-
input: process.stdin,
|
|
553
|
-
output: process.stdout
|
|
554
|
-
});
|
|
555
|
-
const getPrompt = () => chalk9.cyan("\u276F ");
|
|
556
|
-
const processInput = async (line) => {
|
|
557
|
-
const input = line.trim();
|
|
558
|
-
if (!input) return;
|
|
559
|
-
if (input.startsWith("/")) {
|
|
560
|
-
const [cmd, ...args] = input.slice(1).split(" ");
|
|
561
|
-
switch (cmd.toLowerCase()) {
|
|
562
|
-
case "exit":
|
|
563
|
-
case "quit":
|
|
564
|
-
case "q":
|
|
565
|
-
console.log(chalk9.gray("\n \uC885\uB8CC\uD569\uB2C8\uB2E4.\n"));
|
|
566
|
-
rl.close();
|
|
567
|
-
process.exit(0);
|
|
568
|
-
break;
|
|
569
|
-
case "help":
|
|
570
|
-
case "h":
|
|
571
|
-
printHelp();
|
|
572
|
-
break;
|
|
573
|
-
case "clear":
|
|
574
|
-
case "cls":
|
|
575
|
-
console.clear();
|
|
576
|
-
console.log(chalk9.white.bold(` ${current.workflow_name}`));
|
|
577
|
-
console.log(chalk9.cyan("\u2500".repeat(42)));
|
|
578
|
-
break;
|
|
579
|
-
case "workflows":
|
|
580
|
-
case "wf":
|
|
581
|
-
console.log();
|
|
582
|
-
workflows.forEach((w, i) => {
|
|
583
|
-
const marker = w.id === current.id ? chalk9.green("\u25B8") : " ";
|
|
584
|
-
console.log(` ${marker} ${chalk9.cyan(String(i + 1).padStart(2))} ${w.workflow_name}`);
|
|
585
|
-
});
|
|
586
|
-
console.log(chalk9.gray("\n /switch <\uBC88\uD638> \uB85C \uC804\uD658\n"));
|
|
587
|
-
break;
|
|
588
|
-
case "switch":
|
|
589
|
-
case "sw": {
|
|
590
|
-
const num = parseInt(args[0]);
|
|
591
|
-
if (isNaN(num) || num < 1 || num > workflows.length) {
|
|
592
|
-
console.log(chalk9.yellow(` 1~${workflows.length} \uC0AC\uC774 \uBC88\uD638\uB97C \uC785\uB825\uD558\uC138\uC694`));
|
|
593
|
-
} else {
|
|
594
|
-
current = workflows[num - 1];
|
|
595
|
-
turnCount = 0;
|
|
596
|
-
history.length = 0;
|
|
597
|
-
console.log(chalk9.green(`
|
|
598
|
-
\uC804\uD658: ${current.workflow_name}
|
|
599
|
-
`));
|
|
600
|
-
}
|
|
601
|
-
break;
|
|
602
|
-
}
|
|
603
|
-
case "history":
|
|
604
|
-
case "hist":
|
|
605
|
-
if (history.length === 0) {
|
|
606
|
-
console.log(chalk9.gray(" \uB300\uD654 \uC774\uB825\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.\n"));
|
|
607
|
-
} else {
|
|
608
|
-
console.log();
|
|
609
|
-
for (const h of history) {
|
|
610
|
-
const label = h.role === "user" ? chalk9.cyan("\uB098") : chalk9.green("AI");
|
|
611
|
-
const text = h.content.length > 80 ? h.content.slice(0, 80) + "..." : h.content;
|
|
612
|
-
console.log(` ${label}: ${text}`);
|
|
613
|
-
}
|
|
614
|
-
console.log();
|
|
615
|
-
}
|
|
616
|
-
break;
|
|
617
|
-
case "info":
|
|
618
|
-
console.log(`
|
|
619
|
-
${chalk9.gray("\uC11C\uBC84:")} ${server}
|
|
620
|
-
${chalk9.gray("\uC0AC\uC6A9\uC790:")} ${auth.username}
|
|
621
|
-
${chalk9.gray("\uC6CC\uD06C\uD50C\uB85C\uC6B0:")} ${current.workflow_name}
|
|
622
|
-
${chalk9.gray("\uC138\uC158:")} ${sessionId}
|
|
623
|
-
${chalk9.gray("\uD134:")} ${turnCount}
|
|
624
|
-
`);
|
|
625
|
-
break;
|
|
626
|
-
default:
|
|
627
|
-
console.log(chalk9.yellow(` \uC54C \uC218 \uC5C6\uB294 \uCEE4\uB9E8\uB4DC: /${cmd}. /help \uCC38\uACE0`));
|
|
628
|
-
}
|
|
629
|
-
rl.prompt();
|
|
630
|
-
return;
|
|
631
|
-
}
|
|
632
|
-
turnCount++;
|
|
633
|
-
const interactionId = `${sessionId}_t${turnCount}`;
|
|
634
|
-
history.push({ role: "user", content: input });
|
|
635
|
-
process.stdout.write(chalk9.gray(" thinking..."));
|
|
636
|
-
try {
|
|
637
|
-
const stream = await executeWorkflowStream({
|
|
638
|
-
workflow_id: current.id,
|
|
639
|
-
workflow_name: current.workflow_name,
|
|
640
|
-
input_data: input,
|
|
641
|
-
interaction_id: interactionId
|
|
642
|
-
});
|
|
643
|
-
process.stdout.write("\r" + " ".repeat(20) + "\r");
|
|
644
|
-
let fullResponse = "";
|
|
645
|
-
let hasOutput = false;
|
|
646
|
-
await parseSSEStream(
|
|
647
|
-
stream,
|
|
648
|
-
(event) => {
|
|
649
|
-
if ((event.type === "token" || !event.type) && event.content) {
|
|
650
|
-
if (!hasOutput) {
|
|
651
|
-
hasOutput = true;
|
|
652
|
-
console.log();
|
|
653
|
-
}
|
|
654
|
-
process.stdout.write(event.content);
|
|
655
|
-
fullResponse += event.content;
|
|
656
|
-
} else if (event.type === "error") {
|
|
657
|
-
process.stdout.write("\r" + " ".repeat(20) + "\r");
|
|
658
|
-
printError(event.error ?? event.content ?? "\uC624\uB958");
|
|
659
|
-
}
|
|
660
|
-
},
|
|
661
|
-
() => {
|
|
662
|
-
if (hasOutput) {
|
|
663
|
-
console.log();
|
|
664
|
-
console.log();
|
|
665
|
-
}
|
|
666
|
-
if (fullResponse) {
|
|
667
|
-
history.push({ role: "assistant", content: fullResponse });
|
|
668
|
-
}
|
|
669
|
-
},
|
|
670
|
-
(err) => {
|
|
671
|
-
process.stdout.write("\r" + " ".repeat(20) + "\r");
|
|
672
|
-
printError(`\uC2A4\uD2B8\uB9AC\uBC0D \uC624\uB958: ${err.message}`);
|
|
673
|
-
}
|
|
674
|
-
);
|
|
675
|
-
} catch (err) {
|
|
676
|
-
process.stdout.write("\r" + " ".repeat(20) + "\r");
|
|
677
|
-
const msg = err?.response?.data?.detail ?? err.message;
|
|
678
|
-
printError(`\uC2E4\uD589 \uC2E4\uD328: ${msg}`);
|
|
679
|
-
}
|
|
680
|
-
rl.prompt();
|
|
681
|
-
};
|
|
682
|
-
rl.setPrompt(getPrompt());
|
|
683
|
-
rl.prompt();
|
|
684
|
-
rl.on("line", (line) => {
|
|
685
|
-
processInput(line).then(() => {
|
|
686
|
-
});
|
|
687
|
-
});
|
|
688
|
-
rl.on("close", () => {
|
|
689
|
-
console.log(chalk9.gray("\n \uC885\uB8CC\uD569\uB2C8\uB2E4.\n"));
|
|
690
|
-
process.exit(0);
|
|
691
|
-
});
|
|
692
|
-
process.on("SIGINT", () => {
|
|
693
|
-
console.log(chalk9.gray("\n \uC885\uB8CC\uD569\uB2C8\uB2E4.\n"));
|
|
694
|
-
process.exit(0);
|
|
695
|
-
});
|
|
696
|
-
}
|
|
697
|
-
function registerChatCommand(program2) {
|
|
698
|
-
program2.command("chat [workflow-id]").description("\uC778\uD130\uB799\uD2F0\uBE0C \uB300\uD654 \uBAA8\uB4DC").action((workflowId) => chat(workflowId));
|
|
699
|
-
}
|
|
700
|
-
var CHAT_BANNER;
|
|
701
|
-
var init_chat = __esm({
|
|
702
|
-
"src/commands/chat.ts"() {
|
|
703
|
-
"use strict";
|
|
704
|
-
init_store();
|
|
705
|
-
init_workflow();
|
|
706
|
-
init_sse();
|
|
707
|
-
init_format();
|
|
708
|
-
CHAT_BANNER = `
|
|
709
|
-
${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")}
|
|
710
|
-
${chalk9.cyan("\u2502")} ${chalk9.white.bold("XGEN")} ${chalk9.gray("\u2014 \uC6CC\uD06C\uD50C\uB85C\uC6B0 AI \uD130\uBBF8\uB110")} ${chalk9.cyan("\u2502")}
|
|
711
|
-
${chalk9.cyan("\u2502")} ${chalk9.gray("/help \uB3C4\uC6C0\uB9D0 /workflows \uC804\uD658 /exit")} ${chalk9.cyan("\u2502")}
|
|
712
|
-
${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")}`;
|
|
713
|
-
}
|
|
714
|
-
});
|
|
715
|
-
|
|
716
429
|
// src/utils/ui.ts
|
|
717
430
|
import chalk10 from "chalk";
|
|
718
431
|
import { createInterface as createInterface3 } from "readline";
|
|
@@ -728,18 +441,6 @@ function box(lines, color = "cyan") {
|
|
|
728
441
|
});
|
|
729
442
|
return [top, ...body, bot].join("\n");
|
|
730
443
|
}
|
|
731
|
-
function divider(label) {
|
|
732
|
-
if (label) {
|
|
733
|
-
const rest = W - label.length - 6;
|
|
734
|
-
return chalk10.gray(` \u2500\u2500 ${label} ${"\u2500".repeat(Math.max(0, rest))}`);
|
|
735
|
-
}
|
|
736
|
-
return chalk10.gray(" " + "\u2500".repeat(W - 2));
|
|
737
|
-
}
|
|
738
|
-
function statusDot(active, label, detail) {
|
|
739
|
-
const dot = active ? chalk10.green("\u25CF") : chalk10.gray("\u25CB");
|
|
740
|
-
const d = detail ? chalk10.gray(` ${detail}`) : "";
|
|
741
|
-
return ` ${dot} ${label}${d}`;
|
|
742
|
-
}
|
|
743
444
|
function ask(question) {
|
|
744
445
|
return new Promise((resolve) => {
|
|
745
446
|
const rl = createInterface3({ input: process.stdin, output: process.stdout });
|
|
@@ -772,6 +473,11 @@ var init_ui = __esm({
|
|
|
772
473
|
});
|
|
773
474
|
|
|
774
475
|
// src/commands/provider.ts
|
|
476
|
+
var provider_exports = {};
|
|
477
|
+
__export(provider_exports, {
|
|
478
|
+
guidedProviderSetup: () => guidedProviderSetup,
|
|
479
|
+
registerProviderCommand: () => registerProviderCommand
|
|
480
|
+
});
|
|
775
481
|
import chalk11 from "chalk";
|
|
776
482
|
import OpenAI from "openai";
|
|
777
483
|
function detectEnvKey(preset) {
|
|
@@ -1533,170 +1239,6 @@ var init_tools = __esm({
|
|
|
1533
1239
|
}
|
|
1534
1240
|
});
|
|
1535
1241
|
|
|
1536
|
-
// src/mcp/client.ts
|
|
1537
|
-
import { spawn } from "child_process";
|
|
1538
|
-
import { existsSync as existsSync3, readFileSync as readFileSync4 } from "fs";
|
|
1539
|
-
import { join as join3 } from "path";
|
|
1540
|
-
import { createInterface as createInterface4 } from "readline";
|
|
1541
|
-
function loadMcpConfig(dir) {
|
|
1542
|
-
const searchPaths = [
|
|
1543
|
-
dir ? join3(dir, ".mcp.json") : null,
|
|
1544
|
-
join3(process.cwd(), ".mcp.json"),
|
|
1545
|
-
join3(process.env.HOME ?? "", ".mcp.json")
|
|
1546
|
-
].filter(Boolean);
|
|
1547
|
-
for (const p of searchPaths) {
|
|
1548
|
-
if (existsSync3(p)) {
|
|
1549
|
-
try {
|
|
1550
|
-
return JSON.parse(readFileSync4(p, "utf-8"));
|
|
1551
|
-
} catch {
|
|
1552
|
-
continue;
|
|
1553
|
-
}
|
|
1554
|
-
}
|
|
1555
|
-
}
|
|
1556
|
-
return null;
|
|
1557
|
-
}
|
|
1558
|
-
var McpClient, McpManager;
|
|
1559
|
-
var init_client2 = __esm({
|
|
1560
|
-
"src/mcp/client.ts"() {
|
|
1561
|
-
"use strict";
|
|
1562
|
-
McpClient = class {
|
|
1563
|
-
process = null;
|
|
1564
|
-
requestId = 0;
|
|
1565
|
-
pending = /* @__PURE__ */ new Map();
|
|
1566
|
-
serverName;
|
|
1567
|
-
config;
|
|
1568
|
-
tools = [];
|
|
1569
|
-
constructor(serverName, config) {
|
|
1570
|
-
this.serverName = serverName;
|
|
1571
|
-
this.config = config;
|
|
1572
|
-
}
|
|
1573
|
-
async start() {
|
|
1574
|
-
this.process = spawn(this.config.command, this.config.args ?? [], {
|
|
1575
|
-
stdio: ["pipe", "pipe", "pipe"],
|
|
1576
|
-
env: { ...process.env, ...this.config.env }
|
|
1577
|
-
});
|
|
1578
|
-
const rl = createInterface4({ input: this.process.stdout });
|
|
1579
|
-
rl.on("line", (line) => {
|
|
1580
|
-
try {
|
|
1581
|
-
const msg = JSON.parse(line);
|
|
1582
|
-
if (msg.id !== void 0 && this.pending.has(msg.id)) {
|
|
1583
|
-
const p = this.pending.get(msg.id);
|
|
1584
|
-
this.pending.delete(msg.id);
|
|
1585
|
-
if (msg.error) {
|
|
1586
|
-
p.reject(new Error(msg.error.message));
|
|
1587
|
-
} else {
|
|
1588
|
-
p.resolve(msg.result);
|
|
1589
|
-
}
|
|
1590
|
-
}
|
|
1591
|
-
} catch {
|
|
1592
|
-
}
|
|
1593
|
-
});
|
|
1594
|
-
this.process.on("error", (err) => {
|
|
1595
|
-
console.error(`MCP [${this.serverName}] \uD504\uB85C\uC138\uC2A4 \uC624\uB958:`, err.message);
|
|
1596
|
-
});
|
|
1597
|
-
await this.send("initialize", {
|
|
1598
|
-
protocolVersion: "2024-11-05",
|
|
1599
|
-
capabilities: {},
|
|
1600
|
-
clientInfo: { name: "open-xgen", version: "0.3.0" }
|
|
1601
|
-
});
|
|
1602
|
-
await this.send("notifications/initialized", {});
|
|
1603
|
-
}
|
|
1604
|
-
send(method, params) {
|
|
1605
|
-
return new Promise((resolve, reject) => {
|
|
1606
|
-
const id = ++this.requestId;
|
|
1607
|
-
const request = { jsonrpc: "2.0", id, method, params };
|
|
1608
|
-
this.pending.set(id, { resolve, reject });
|
|
1609
|
-
const timeout = setTimeout(() => {
|
|
1610
|
-
this.pending.delete(id);
|
|
1611
|
-
reject(new Error(`MCP \uC694\uCCAD \uD0C0\uC784\uC544\uC6C3: ${method}`));
|
|
1612
|
-
}, 15e3);
|
|
1613
|
-
this.pending.set(id, {
|
|
1614
|
-
resolve: (v) => {
|
|
1615
|
-
clearTimeout(timeout);
|
|
1616
|
-
resolve(v);
|
|
1617
|
-
},
|
|
1618
|
-
reject: (e) => {
|
|
1619
|
-
clearTimeout(timeout);
|
|
1620
|
-
reject(e);
|
|
1621
|
-
}
|
|
1622
|
-
});
|
|
1623
|
-
this.process?.stdin?.write(JSON.stringify(request) + "\n");
|
|
1624
|
-
});
|
|
1625
|
-
}
|
|
1626
|
-
async listTools() {
|
|
1627
|
-
const result = await this.send("tools/list", {});
|
|
1628
|
-
this.tools = result.tools ?? [];
|
|
1629
|
-
return this.tools;
|
|
1630
|
-
}
|
|
1631
|
-
async callTool(name, args) {
|
|
1632
|
-
const result = await this.send("tools/call", { name, arguments: args });
|
|
1633
|
-
return result.content?.map((c) => c.text ?? "").join("\n") ?? "";
|
|
1634
|
-
}
|
|
1635
|
-
getOpenAITools() {
|
|
1636
|
-
return this.tools.map((t) => ({
|
|
1637
|
-
type: "function",
|
|
1638
|
-
function: {
|
|
1639
|
-
name: `mcp_${this.serverName}_${t.name}`,
|
|
1640
|
-
description: `[MCP:${this.serverName}] ${t.description ?? t.name}`,
|
|
1641
|
-
parameters: t.inputSchema ?? { type: "object", properties: {} }
|
|
1642
|
-
}
|
|
1643
|
-
}));
|
|
1644
|
-
}
|
|
1645
|
-
stop() {
|
|
1646
|
-
this.process?.kill();
|
|
1647
|
-
this.process = null;
|
|
1648
|
-
}
|
|
1649
|
-
};
|
|
1650
|
-
McpManager = class {
|
|
1651
|
-
clients = /* @__PURE__ */ new Map();
|
|
1652
|
-
async startAll(config) {
|
|
1653
|
-
for (const [name, serverConfig] of Object.entries(config.mcpServers)) {
|
|
1654
|
-
if (serverConfig.type !== "stdio") continue;
|
|
1655
|
-
try {
|
|
1656
|
-
const client2 = new McpClient(name, serverConfig);
|
|
1657
|
-
await client2.start();
|
|
1658
|
-
await client2.listTools();
|
|
1659
|
-
this.clients.set(name, client2);
|
|
1660
|
-
} catch (err) {
|
|
1661
|
-
console.error(`MCP [${name}] \uC2DC\uC791 \uC2E4\uD328:`, err.message);
|
|
1662
|
-
}
|
|
1663
|
-
}
|
|
1664
|
-
}
|
|
1665
|
-
getAllTools() {
|
|
1666
|
-
const tools2 = [];
|
|
1667
|
-
for (const client2 of this.clients.values()) {
|
|
1668
|
-
tools2.push(...client2.getOpenAITools());
|
|
1669
|
-
}
|
|
1670
|
-
return tools2;
|
|
1671
|
-
}
|
|
1672
|
-
async callTool(fullName, args) {
|
|
1673
|
-
const parts = fullName.split("_");
|
|
1674
|
-
if (parts.length < 3 || parts[0] !== "mcp") return `Unknown MCP tool: ${fullName}`;
|
|
1675
|
-
const serverName = parts[1];
|
|
1676
|
-
const toolName = parts.slice(2).join("_");
|
|
1677
|
-
const client2 = this.clients.get(serverName);
|
|
1678
|
-
if (!client2) return `MCP \uC11C\uBC84\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${serverName}`;
|
|
1679
|
-
return client2.callTool(toolName, args);
|
|
1680
|
-
}
|
|
1681
|
-
isMcpTool(name) {
|
|
1682
|
-
return name.startsWith("mcp_");
|
|
1683
|
-
}
|
|
1684
|
-
stopAll() {
|
|
1685
|
-
for (const client2 of this.clients.values()) {
|
|
1686
|
-
client2.stop();
|
|
1687
|
-
}
|
|
1688
|
-
this.clients.clear();
|
|
1689
|
-
}
|
|
1690
|
-
get serverCount() {
|
|
1691
|
-
return this.clients.size;
|
|
1692
|
-
}
|
|
1693
|
-
getServerNames() {
|
|
1694
|
-
return [...this.clients.keys()];
|
|
1695
|
-
}
|
|
1696
|
-
};
|
|
1697
|
-
}
|
|
1698
|
-
});
|
|
1699
|
-
|
|
1700
1242
|
// src/api/document.ts
|
|
1701
1243
|
var document_exports = {};
|
|
1702
1244
|
__export(document_exports, {
|
|
@@ -1785,532 +1327,445 @@ var init_ontology = __esm({
|
|
|
1785
1327
|
}
|
|
1786
1328
|
});
|
|
1787
1329
|
|
|
1788
|
-
// src/
|
|
1789
|
-
|
|
1790
|
-
__export(home_exports, {
|
|
1791
|
-
homeMenu: () => homeMenu
|
|
1792
|
-
});
|
|
1793
|
-
import chalk12 from "chalk";
|
|
1794
|
-
function showStatus() {
|
|
1795
|
-
const provider = getDefaultProvider();
|
|
1330
|
+
// src/agent/tools/xgen-api.ts
|
|
1331
|
+
async function execute8(name, args) {
|
|
1796
1332
|
const server = getServer();
|
|
1797
1333
|
const auth = getAuth();
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
console.log(divider("\uC0C1\uD0DC"));
|
|
1801
|
-
console.log();
|
|
1802
|
-
console.log(provider ? statusDot(true, chalk12.bold("AI \uC5D0\uC774\uC804\uD2B8"), `${provider.name} \xB7 ${provider.model}`) : statusDot(false, "AI \uC5D0\uC774\uC804\uD2B8", "\uBBF8\uC124\uC815"));
|
|
1803
|
-
console.log(server && auth ? statusDot(true, chalk12.bold("XGEN \uC11C\uBC84"), `${auth.username} \xB7 ${server.replace("https://", "")}`) : server ? statusDot(false, "XGEN \uC11C\uBC84", `${server.replace("https://", "")} \xB7 \uB85C\uADF8\uC778 \uD544\uC694`) : statusDot(false, "XGEN \uC11C\uBC84", "\uBBF8\uC5F0\uACB0"));
|
|
1804
|
-
if (activeEnv) {
|
|
1805
|
-
console.log(statusDot(true, chalk12.bold("\uD658\uACBD"), `${activeEnv.name} (${envs.length}\uAC1C \uB4F1\uB85D)`));
|
|
1806
|
-
} else if (envs.length > 0) {
|
|
1807
|
-
console.log(statusDot(false, "\uD658\uACBD", `${envs.length}\uAC1C \uB4F1\uB85D`));
|
|
1334
|
+
if (!server || !auth) {
|
|
1335
|
+
return "XGEN \uC11C\uBC84\uC5D0 \uC5F0\uACB0\uB418\uC5B4 \uC788\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. /connect \uBA85\uB839\uC73C\uB85C \uC5F0\uACB0\uD558\uC138\uC694.";
|
|
1808
1336
|
}
|
|
1809
|
-
|
|
1337
|
+
try {
|
|
1338
|
+
switch (name) {
|
|
1339
|
+
case "xgen_workflow_list":
|
|
1340
|
+
return await workflowList2();
|
|
1341
|
+
case "xgen_workflow_run":
|
|
1342
|
+
return await workflowRun2(args);
|
|
1343
|
+
case "xgen_workflow_info":
|
|
1344
|
+
return await workflowInfo2(args);
|
|
1345
|
+
case "xgen_doc_list":
|
|
1346
|
+
return await docList(args);
|
|
1347
|
+
case "xgen_ontology_query":
|
|
1348
|
+
return await ontologyQuery(args);
|
|
1349
|
+
case "xgen_server_status":
|
|
1350
|
+
return await serverStatus();
|
|
1351
|
+
case "xgen_execution_history":
|
|
1352
|
+
return await executionHistory(args);
|
|
1353
|
+
default:
|
|
1354
|
+
return `Unknown XGEN tool: ${name}`;
|
|
1355
|
+
}
|
|
1356
|
+
} catch (err) {
|
|
1357
|
+
return `XGEN API \uC624\uB958: ${err.message}`;
|
|
1358
|
+
}
|
|
1359
|
+
}
|
|
1360
|
+
function isXgenTool(name) {
|
|
1361
|
+
return name.startsWith("xgen_");
|
|
1362
|
+
}
|
|
1363
|
+
async function workflowList2() {
|
|
1364
|
+
const { getWorkflowListDetail: getWorkflowListDetail2 } = await Promise.resolve().then(() => (init_workflow(), workflow_exports));
|
|
1365
|
+
const wfs = await getWorkflowListDetail2();
|
|
1366
|
+
if (!wfs.length) return "\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uC5C6\uC74C.";
|
|
1367
|
+
return wfs.map((w, i) => {
|
|
1368
|
+
const deployed = w.is_deployed;
|
|
1369
|
+
const dk = w.deploy_key;
|
|
1370
|
+
const tag = deployed ? " [\uBC30\uD3EC\uB428]" : "";
|
|
1371
|
+
return `${i + 1}. ${w.workflow_name}${tag}
|
|
1372
|
+
ID: ${w.workflow_id ?? w.id}
|
|
1373
|
+
deploy_key: ${dk || "\uC5C6\uC74C"}`;
|
|
1374
|
+
}).join("\n");
|
|
1375
|
+
}
|
|
1376
|
+
async function workflowRun2(args) {
|
|
1377
|
+
const { executeWorkflow: executeWorkflow2 } = await Promise.resolve().then(() => (init_workflow(), workflow_exports));
|
|
1378
|
+
const { randomUUID: randomUUID4 } = await import("crypto");
|
|
1379
|
+
const result = await executeWorkflow2({
|
|
1380
|
+
workflow_id: args.workflow_id,
|
|
1381
|
+
workflow_name: args.workflow_name,
|
|
1382
|
+
input_data: args.input_data,
|
|
1383
|
+
interaction_id: `cli_${randomUUID4().slice(0, 8)}`,
|
|
1384
|
+
deploy_key: args.deploy_key
|
|
1385
|
+
});
|
|
1386
|
+
if (result.content) return String(result.content);
|
|
1387
|
+
if (result.success === false) return `\uC624\uB958: ${result.error ?? result.message}`;
|
|
1388
|
+
return JSON.stringify(result, null, 2).slice(0, 2e3);
|
|
1389
|
+
}
|
|
1390
|
+
async function workflowInfo2(args) {
|
|
1391
|
+
const { getWorkflowDetail: getWorkflowDetail2 } = await Promise.resolve().then(() => (init_workflow(), workflow_exports));
|
|
1392
|
+
const detail = await getWorkflowDetail2(args.workflow_id);
|
|
1393
|
+
const nodes = detail.nodes?.length ?? 0;
|
|
1394
|
+
const edges = detail.edges?.length ?? 0;
|
|
1395
|
+
return `\uC6CC\uD06C\uD50C\uB85C\uC6B0: ${detail.workflow_name}
|
|
1396
|
+
ID: ${detail.id}
|
|
1397
|
+
\uB178\uB4DC: ${nodes}\uAC1C
|
|
1398
|
+
\uC5E3\uC9C0: ${edges}\uAC1C`;
|
|
1399
|
+
}
|
|
1400
|
+
async function docList(args) {
|
|
1401
|
+
const { listDocuments: listDocuments2 } = await Promise.resolve().then(() => (init_document(), document_exports));
|
|
1402
|
+
const docs = await listDocuments2(args.collection_id);
|
|
1403
|
+
if (!docs.length) return "\uBB38\uC11C \uC5C6\uC74C.";
|
|
1404
|
+
return docs.map(
|
|
1405
|
+
(d, i) => `${i + 1}. ${d.file_name ?? d.name ?? "-"} (${d.file_type ?? "-"}) \u2014 ${d.status ?? "-"}`
|
|
1406
|
+
).join("\n");
|
|
1407
|
+
}
|
|
1408
|
+
async function ontologyQuery(args) {
|
|
1409
|
+
const { queryGraphRAG: queryGraphRAG2 } = await Promise.resolve().then(() => (init_ontology(), ontology_exports));
|
|
1410
|
+
const result = await queryGraphRAG2(args.query, args.graph_id);
|
|
1411
|
+
let output = "";
|
|
1412
|
+
if (result.answer) output += `\uB2F5\uBCC0: ${result.answer}
|
|
1413
|
+
`;
|
|
1414
|
+
if (result.sources?.length) output += `\uCD9C\uCC98: ${result.sources.join(", ")}
|
|
1415
|
+
`;
|
|
1416
|
+
if (result.triples_used?.length) output += `\uD2B8\uB9AC\uD50C: ${result.triples_used.join("; ")}`;
|
|
1417
|
+
return output || "\uACB0\uACFC \uC5C6\uC74C.";
|
|
1810
1418
|
}
|
|
1811
|
-
async function
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1419
|
+
async function serverStatus() {
|
|
1420
|
+
const server = getServer();
|
|
1421
|
+
const auth = getAuth();
|
|
1422
|
+
return `\uC11C\uBC84: ${server}
|
|
1423
|
+
\uC0AC\uC6A9\uC790: ${auth?.username}
|
|
1424
|
+
User ID: ${auth?.userId}`;
|
|
1425
|
+
}
|
|
1426
|
+
async function executionHistory(args) {
|
|
1427
|
+
const { getIOLogs: getIOLogs2 } = await Promise.resolve().then(() => (init_workflow(), workflow_exports));
|
|
1428
|
+
const limit = args.limit || 10;
|
|
1429
|
+
const logs = await getIOLogs2(void 0, limit);
|
|
1430
|
+
if (!logs.length) return "\uC2E4\uD589 \uC774\uB825 \uC5C6\uC74C.";
|
|
1431
|
+
return logs.map(
|
|
1432
|
+
(l, i) => `${i + 1}. [${l.created_at ?? ""}]
|
|
1433
|
+
\uC785\uB825: ${(l.input_data ?? "").slice(0, 80)}
|
|
1434
|
+
\uCD9C\uB825: ${(l.output_data ?? "").slice(0, 80)}`
|
|
1435
|
+
).join("\n");
|
|
1436
|
+
}
|
|
1437
|
+
var definitions;
|
|
1438
|
+
var init_xgen_api = __esm({
|
|
1439
|
+
"src/agent/tools/xgen-api.ts"() {
|
|
1440
|
+
"use strict";
|
|
1441
|
+
init_store();
|
|
1442
|
+
definitions = [
|
|
1443
|
+
{
|
|
1444
|
+
type: "function",
|
|
1445
|
+
function: {
|
|
1446
|
+
name: "xgen_workflow_list",
|
|
1447
|
+
description: "XGEN \uC11C\uBC84\uC5D0\uC11C \uC6CC\uD06C\uD50C\uB85C\uC6B0 \uBAA9\uB85D\uC744 \uAC00\uC838\uC635\uB2C8\uB2E4.",
|
|
1448
|
+
parameters: { type: "object", properties: {} }
|
|
1840
1449
|
}
|
|
1841
|
-
}
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
wfs.forEach((w, i) => {
|
|
1857
|
-
const id = (w.workflow_id ?? w.id ?? "").toString();
|
|
1858
|
-
const deployed = w.is_deployed;
|
|
1859
|
-
const tag = deployed ? chalk12.green(" [\uBC30\uD3EC]") : "";
|
|
1860
|
-
console.log(` ${chalk12.cyan(`${String(i + 1).padStart(3)}.`)} ${w.workflow_name}${tag}`);
|
|
1861
|
-
console.log(` ${chalk12.gray(id)}`);
|
|
1862
|
-
});
|
|
1863
|
-
console.log();
|
|
1864
|
-
console.log(chalk12.gray(" \uBC88\uD638 \uC785\uB825 \u2192 \uC2E4\uD589 / Enter \u2192 \uB3CC\uC544\uAC00\uAE30"));
|
|
1865
|
-
const choice2 = await ask(chalk12.cyan("\n \u276F "));
|
|
1866
|
-
if (!choice2) return;
|
|
1867
|
-
const wi = parseInt(choice2) - 1;
|
|
1868
|
-
if (wi < 0 || wi >= wfs.length) return;
|
|
1869
|
-
const selected2 = wfs[wi];
|
|
1870
|
-
const wfId = (selected2.workflow_id ?? selected2.id ?? "").toString();
|
|
1871
|
-
console.log(chalk12.green(`
|
|
1872
|
-
\u2713 ${selected2.workflow_name}
|
|
1873
|
-
`));
|
|
1874
|
-
const input = await ask(chalk12.white(" \uBA54\uC2DC\uC9C0: "));
|
|
1875
|
-
if (!input) return;
|
|
1876
|
-
const deployKey = selected2.deploy_key;
|
|
1877
|
-
const isDeployed = selected2.is_deployed;
|
|
1878
|
-
try {
|
|
1879
|
-
console.log(chalk12.gray("\n \uC2E4\uD589 \uC911...\n"));
|
|
1880
|
-
const { executeWorkflow: executeWorkflow2 } = await Promise.resolve().then(() => (init_workflow(), workflow_exports));
|
|
1881
|
-
const { randomUUID: randomUUID4 } = await import("crypto");
|
|
1882
|
-
const result = await executeWorkflow2({
|
|
1883
|
-
workflow_id: wfId,
|
|
1884
|
-
workflow_name: selected2.workflow_name,
|
|
1885
|
-
input_data: input,
|
|
1886
|
-
interaction_id: `cli_${randomUUID4().slice(0, 8)}`,
|
|
1887
|
-
deploy_key: isDeployed && deployKey ? deployKey : void 0
|
|
1888
|
-
});
|
|
1889
|
-
if (result.content) {
|
|
1890
|
-
console.log(chalk12.bold(" \uC751\uB2F5:"));
|
|
1891
|
-
console.log(` ${result.content}
|
|
1892
|
-
`);
|
|
1893
|
-
} else if (result.success === false) {
|
|
1894
|
-
console.log(chalk12.red(` \uC624\uB958: ${result.error ?? result.message}
|
|
1895
|
-
`));
|
|
1896
|
-
} else {
|
|
1897
|
-
console.log(chalk12.gray(JSON.stringify(result, null, 2).slice(0, 500)));
|
|
1898
|
-
console.log();
|
|
1899
|
-
}
|
|
1900
|
-
} catch (err) {
|
|
1901
|
-
console.log(chalk12.red(` \uC2E4\uD589 \uC2E4\uD328: ${err.message}
|
|
1902
|
-
`));
|
|
1450
|
+
},
|
|
1451
|
+
{
|
|
1452
|
+
type: "function",
|
|
1453
|
+
function: {
|
|
1454
|
+
name: "xgen_workflow_run",
|
|
1455
|
+
description: "XGEN \uC6CC\uD06C\uD50C\uB85C\uC6B0\uB97C \uC2E4\uD589\uD569\uB2C8\uB2E4. \uBC30\uD3EC\uB41C \uC6CC\uD06C\uD50C\uB85C\uC6B0\uB9CC \uC2E4\uD589 \uAC00\uB2A5.",
|
|
1456
|
+
parameters: {
|
|
1457
|
+
type: "object",
|
|
1458
|
+
properties: {
|
|
1459
|
+
workflow_id: { type: "string", description: "\uC6CC\uD06C\uD50C\uB85C\uC6B0 ID" },
|
|
1460
|
+
workflow_name: { type: "string", description: "\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uC774\uB984" },
|
|
1461
|
+
input_data: { type: "string", description: "\uC785\uB825 \uBA54\uC2DC\uC9C0" },
|
|
1462
|
+
deploy_key: { type: "string", description: "\uBC30\uD3EC \uD0A4 (\uBC30\uD3EC\uB41C \uC6CC\uD06C\uD50C\uB85C\uC6B0)" }
|
|
1463
|
+
},
|
|
1464
|
+
required: ["workflow_id", "workflow_name", "input_data"]
|
|
1903
1465
|
}
|
|
1904
1466
|
}
|
|
1905
|
-
}
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
}
|
|
1918
|
-
console.log(chalk12.bold(`
|
|
1919
|
-
\uBB38\uC11C (${docs.length}\uAC1C)
|
|
1920
|
-
`));
|
|
1921
|
-
docs.forEach((d, i) => {
|
|
1922
|
-
console.log(` ${chalk12.cyan(`${i + 1}.`)} ${d.file_name ?? d.name ?? "-"} ${chalk12.gray(d.file_type ?? "")}`);
|
|
1923
|
-
});
|
|
1924
|
-
console.log();
|
|
1925
|
-
} catch (err) {
|
|
1926
|
-
console.log(chalk12.red(` \uC624\uB958: ${err.message}
|
|
1927
|
-
`));
|
|
1467
|
+
},
|
|
1468
|
+
{
|
|
1469
|
+
type: "function",
|
|
1470
|
+
function: {
|
|
1471
|
+
name: "xgen_workflow_info",
|
|
1472
|
+
description: "\uD2B9\uC815 \uC6CC\uD06C\uD50C\uB85C\uC6B0\uC758 \uC0C1\uC138 \uC815\uBCF4(\uB178\uB4DC, \uC5E3\uC9C0 \uB4F1)\uB97C \uAC00\uC838\uC635\uB2C8\uB2E4.",
|
|
1473
|
+
parameters: {
|
|
1474
|
+
type: "object",
|
|
1475
|
+
properties: {
|
|
1476
|
+
workflow_id: { type: "string", description: "\uC6CC\uD06C\uD50C\uB85C\uC6B0 ID" }
|
|
1477
|
+
},
|
|
1478
|
+
required: ["workflow_id"]
|
|
1928
1479
|
}
|
|
1929
1480
|
}
|
|
1930
|
-
}
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
const { queryGraphRAG: queryGraphRAG2 } = await Promise.resolve().then(() => (init_ontology(), ontology_exports));
|
|
1941
|
-
const result = await queryGraphRAG2(question);
|
|
1942
|
-
if (result.answer) {
|
|
1943
|
-
console.log(chalk12.bold(" \uB2F5\uBCC0:"));
|
|
1944
|
-
console.log(` ${result.answer}`);
|
|
1945
|
-
}
|
|
1946
|
-
if (result.sources?.length) {
|
|
1947
|
-
console.log(chalk12.bold("\n \uCD9C\uCC98:"));
|
|
1948
|
-
result.sources.forEach((s) => console.log(chalk12.gray(` - ${s}`)));
|
|
1481
|
+
},
|
|
1482
|
+
{
|
|
1483
|
+
type: "function",
|
|
1484
|
+
function: {
|
|
1485
|
+
name: "xgen_doc_list",
|
|
1486
|
+
description: "XGEN \uC11C\uBC84\uC5D0\uC11C \uBB38\uC11C \uBAA9\uB85D\uC744 \uAC00\uC838\uC635\uB2C8\uB2E4.",
|
|
1487
|
+
parameters: {
|
|
1488
|
+
type: "object",
|
|
1489
|
+
properties: {
|
|
1490
|
+
collection_id: { type: "string", description: "\uCEEC\uB809\uC158 ID (\uC120\uD0DD)" }
|
|
1949
1491
|
}
|
|
1950
|
-
console.log();
|
|
1951
|
-
} catch (err) {
|
|
1952
|
-
console.log(chalk12.red(` \uC624\uB958: ${err.message}
|
|
1953
|
-
`));
|
|
1954
1492
|
}
|
|
1955
1493
|
}
|
|
1956
|
-
}
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1494
|
+
},
|
|
1495
|
+
{
|
|
1496
|
+
type: "function",
|
|
1497
|
+
function: {
|
|
1498
|
+
name: "xgen_ontology_query",
|
|
1499
|
+
description: "\uC628\uD1A8\uB85C\uC9C0(GraphRAG)\uC5D0 \uC9C8\uBB38\uD569\uB2C8\uB2E4. \uC9C0\uC2DD \uADF8\uB798\uD504 \uAE30\uBC18 \uAC80\uC0C9.",
|
|
1500
|
+
parameters: {
|
|
1501
|
+
type: "object",
|
|
1502
|
+
properties: {
|
|
1503
|
+
query: { type: "string", description: "\uC9C8\uC758 \uB0B4\uC6A9" },
|
|
1504
|
+
graph_id: { type: "string", description: "\uADF8\uB798\uD504 ID (\uC120\uD0DD)" }
|
|
1505
|
+
},
|
|
1506
|
+
required: ["query"]
|
|
1507
|
+
}
|
|
1508
|
+
}
|
|
1509
|
+
},
|
|
1510
|
+
{
|
|
1511
|
+
type: "function",
|
|
1512
|
+
function: {
|
|
1513
|
+
name: "xgen_server_status",
|
|
1514
|
+
description: "XGEN \uC11C\uBC84 \uC0C1\uD0DC\uB97C \uD655\uC778\uD569\uB2C8\uB2E4.",
|
|
1515
|
+
parameters: { type: "object", properties: {} }
|
|
1516
|
+
}
|
|
1517
|
+
},
|
|
1518
|
+
{
|
|
1519
|
+
type: "function",
|
|
1520
|
+
function: {
|
|
1521
|
+
name: "xgen_execution_history",
|
|
1522
|
+
description: "\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uC2E4\uD589 \uC774\uB825\uC744 \uAC00\uC838\uC635\uB2C8\uB2E4.",
|
|
1523
|
+
parameters: {
|
|
1524
|
+
type: "object",
|
|
1525
|
+
properties: {
|
|
1526
|
+
limit: { type: "number", description: "\uAC00\uC838\uC62C \uC774\uB825 \uC218 (\uAE30\uBCF8 10)" }
|
|
1968
1527
|
}
|
|
1969
|
-
console.log(chalk12.bold(`
|
|
1970
|
-
\uCD5C\uADFC \uC2E4\uD589 \uC774\uB825 (${logs.length}\uAC1C)
|
|
1971
|
-
`));
|
|
1972
|
-
logs.forEach((log, i) => {
|
|
1973
|
-
console.log(` ${chalk12.cyan(`${i + 1}.`)} ${chalk12.gray(log.created_at ?? "-")}`);
|
|
1974
|
-
console.log(` \uC785\uB825: ${(log.input_data ?? "").slice(0, 50)}`);
|
|
1975
|
-
console.log(` \uCD9C\uB825: ${chalk12.gray((log.output_data ?? "").slice(0, 50))}`);
|
|
1976
|
-
});
|
|
1977
|
-
console.log();
|
|
1978
|
-
} catch (err) {
|
|
1979
|
-
console.log(chalk12.red(` \uC624\uB958: ${err.message}
|
|
1980
|
-
`));
|
|
1981
1528
|
}
|
|
1982
1529
|
}
|
|
1983
|
-
});
|
|
1984
|
-
}
|
|
1985
|
-
items.push({
|
|
1986
|
-
key: "s",
|
|
1987
|
-
label: hasServer ? "\uC11C\uBC84 \uC7AC\uC124\uC815" : chalk12.bold("XGEN \uC11C\uBC84 \uC5F0\uACB0"),
|
|
1988
|
-
hint: hasServer ? "\uC11C\uBC84 \uBCC0\uACBD / \uC7AC\uB85C\uADF8\uC778" : "URL + \uB85C\uADF8\uC778",
|
|
1989
|
-
action: async () => {
|
|
1990
|
-
await serverSetup();
|
|
1991
|
-
showStatus();
|
|
1992
|
-
}
|
|
1993
|
-
});
|
|
1994
|
-
items.push({
|
|
1995
|
-
key: "p",
|
|
1996
|
-
label: "\uD504\uB85C\uBC14\uC774\uB354 \uAD00\uB9AC",
|
|
1997
|
-
hint: `${getProviders().length}\uAC1C \uB4F1\uB85D`,
|
|
1998
|
-
action: async () => {
|
|
1999
|
-
await providerMenu();
|
|
2000
|
-
showStatus();
|
|
2001
|
-
}
|
|
2002
|
-
});
|
|
2003
|
-
items.push({
|
|
2004
|
-
key: "e",
|
|
2005
|
-
label: "\uD658\uACBD \uAD00\uB9AC",
|
|
2006
|
-
hint: `${getEnvironments().length}\uAC1C \uB4F1\uB85D \u2014 \uC11C\uBC84 \uC804\uD658`,
|
|
2007
|
-
action: async () => {
|
|
2008
|
-
await environmentMenu();
|
|
2009
|
-
showStatus();
|
|
2010
|
-
}
|
|
2011
|
-
});
|
|
2012
|
-
console.log(divider("\uBA54\uB274"));
|
|
2013
|
-
console.log();
|
|
2014
|
-
if (hasServer) {
|
|
2015
|
-
console.log(chalk12.gray(" AI"));
|
|
2016
|
-
}
|
|
2017
|
-
const aiItem = items.find((i) => i.key === "a");
|
|
2018
|
-
console.log(` ${chalk12.cyan.bold(aiItem.key + ".")} ${aiItem.label} ${chalk12.gray("\u2014 " + aiItem.hint)}`);
|
|
2019
|
-
if (hasServer) {
|
|
2020
|
-
console.log();
|
|
2021
|
-
console.log(chalk12.gray(" XGEN \uD50C\uB7AB\uD3FC"));
|
|
2022
|
-
for (const item of items.filter((i) => ["c", "w", "r", "d", "o", "h"].includes(i.key))) {
|
|
2023
|
-
console.log(` ${chalk12.cyan.bold(item.key + ".")} ${item.label} ${chalk12.gray("\u2014 " + item.hint)}`);
|
|
2024
1530
|
}
|
|
2025
|
-
|
|
2026
|
-
console.log();
|
|
2027
|
-
console.log(chalk12.gray(" \uC124\uC815"));
|
|
2028
|
-
for (const item of items.filter((i) => ["s", "p", "e"].includes(i.key))) {
|
|
2029
|
-
console.log(` ${chalk12.cyan.bold(item.key + ".")} ${item.label} ${chalk12.gray("\u2014 " + item.hint)}`);
|
|
2030
|
-
}
|
|
2031
|
-
console.log(` ${chalk12.gray("q. \uC885\uB8CC")}`);
|
|
2032
|
-
console.log();
|
|
2033
|
-
const choice = await ask(chalk12.cyan(" \u276F "));
|
|
2034
|
-
if (choice === "q" || choice === "exit") {
|
|
2035
|
-
console.log(chalk12.gray("\n \u{1F44B}\n"));
|
|
2036
|
-
break;
|
|
2037
|
-
}
|
|
2038
|
-
if (!choice) continue;
|
|
2039
|
-
const selected = items.find((i) => i.key === choice);
|
|
2040
|
-
if (!selected) {
|
|
2041
|
-
console.log(chalk12.red(` "${choice}" \u2014 \uC798\uBABB\uB41C \uC785\uB825
|
|
2042
|
-
`));
|
|
2043
|
-
continue;
|
|
2044
|
-
}
|
|
2045
|
-
try {
|
|
2046
|
-
await selected.action();
|
|
2047
|
-
} catch (err) {
|
|
2048
|
-
console.log(chalk12.red(`
|
|
2049
|
-
\uC624\uB958: ${err.message}
|
|
2050
|
-
`));
|
|
2051
|
-
}
|
|
2052
|
-
}
|
|
2053
|
-
}
|
|
2054
|
-
async function serverSetup() {
|
|
2055
|
-
console.log();
|
|
2056
|
-
console.log(box(["XGEN \uC11C\uBC84 \uC5F0\uACB0"]));
|
|
2057
|
-
console.log();
|
|
2058
|
-
const currentServer = getServer();
|
|
2059
|
-
const urlInput = await ask(
|
|
2060
|
-
chalk12.white(` \uC11C\uBC84 URL${currentServer ? chalk12.gray(` [${currentServer}]`) : ""}: `)
|
|
2061
|
-
);
|
|
2062
|
-
const url = urlInput || currentServer;
|
|
2063
|
-
if (!url) {
|
|
2064
|
-
console.log(chalk12.red(" URL \uD544\uC694.\n"));
|
|
2065
|
-
return;
|
|
2066
|
-
}
|
|
2067
|
-
const { setServer: setServer2 } = await Promise.resolve().then(() => (init_store(), store_exports));
|
|
2068
|
-
setServer2(url);
|
|
2069
|
-
console.log(chalk12.green(` \u2713 ${url}
|
|
2070
|
-
`));
|
|
2071
|
-
const email = await ask(chalk12.white(" \uC774\uBA54\uC77C: "));
|
|
2072
|
-
const password = await ask(chalk12.white(" \uBE44\uBC00\uBC88\uD638: "));
|
|
2073
|
-
if (!email || !password) {
|
|
2074
|
-
console.log(chalk12.red(" \uD544\uC694.\n"));
|
|
2075
|
-
return;
|
|
2076
|
-
}
|
|
2077
|
-
try {
|
|
2078
|
-
const { apiLogin: apiLogin2 } = await Promise.resolve().then(() => (init_auth(), auth_exports));
|
|
2079
|
-
const { setAuth: setAuth2 } = await Promise.resolve().then(() => (init_store(), store_exports));
|
|
2080
|
-
const result = await apiLogin2(email, password);
|
|
2081
|
-
if (result.success && result.access_token) {
|
|
2082
|
-
setAuth2({
|
|
2083
|
-
accessToken: result.access_token,
|
|
2084
|
-
refreshToken: result.refresh_token ?? "",
|
|
2085
|
-
userId: result.user_id ?? "",
|
|
2086
|
-
username: result.username ?? "",
|
|
2087
|
-
isAdmin: false,
|
|
2088
|
-
expiresAt: null
|
|
2089
|
-
});
|
|
2090
|
-
console.log(chalk12.green(`
|
|
2091
|
-
\u2713 \uB85C\uADF8\uC778 \uC131\uACF5! ${chalk12.bold(result.username ?? email)}
|
|
2092
|
-
`));
|
|
2093
|
-
} else {
|
|
2094
|
-
console.log(chalk12.red(`
|
|
2095
|
-
\u2717 ${result.message}
|
|
2096
|
-
`));
|
|
2097
|
-
}
|
|
2098
|
-
} catch (err) {
|
|
2099
|
-
console.log(chalk12.red(`
|
|
2100
|
-
\u2717 ${err.message}
|
|
2101
|
-
`));
|
|
2102
|
-
}
|
|
2103
|
-
}
|
|
2104
|
-
async function providerMenu() {
|
|
2105
|
-
const providers = getProviders();
|
|
2106
|
-
const defaultP = getDefaultProvider();
|
|
2107
|
-
console.log();
|
|
2108
|
-
console.log(box(["\uD504\uB85C\uBC14\uC774\uB354 \uAD00\uB9AC"]));
|
|
2109
|
-
console.log();
|
|
2110
|
-
if (providers.length > 0) {
|
|
2111
|
-
for (const p of providers) {
|
|
2112
|
-
const mark = p.id === defaultP?.id ? chalk12.green("\u25CF ") : chalk12.gray(" ");
|
|
2113
|
-
console.log(` ${mark}${chalk12.bold(p.name)} ${chalk12.gray(`${p.type} \xB7 ${p.model}`)}`);
|
|
2114
|
-
}
|
|
2115
|
-
console.log();
|
|
2116
|
-
} else {
|
|
2117
|
-
console.log(chalk12.gray(" \uC5C6\uC74C\n"));
|
|
1531
|
+
];
|
|
2118
1532
|
}
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
}
|
|
2140
|
-
} else if (opts[ci - 1] === "\uC0AD\uC81C") {
|
|
2141
|
-
console.log();
|
|
2142
|
-
providers.forEach((p, i) => console.log(` ${chalk12.cyan(`${i + 1}.`)} ${p.name} (${p.model})`));
|
|
2143
|
-
console.log();
|
|
2144
|
-
const di = parseInt(await ask(chalk12.white(" \uC0AD\uC81C \uBC88\uD638: "))) - 1;
|
|
2145
|
-
if (di >= 0 && di < providers.length) {
|
|
2146
|
-
const { removeProvider: removeProvider2 } = await Promise.resolve().then(() => (init_store(), store_exports));
|
|
2147
|
-
removeProvider2(providers[di].id);
|
|
2148
|
-
console.log(chalk12.green(` \u2713 \uC0AD\uC81C: ${providers[di].name}
|
|
2149
|
-
`));
|
|
1533
|
+
});
|
|
1534
|
+
|
|
1535
|
+
// src/mcp/client.ts
|
|
1536
|
+
import { spawn } from "child_process";
|
|
1537
|
+
import { existsSync as existsSync3, readFileSync as readFileSync4 } from "fs";
|
|
1538
|
+
import { join as join3 } from "path";
|
|
1539
|
+
import { createInterface as createInterface4 } from "readline";
|
|
1540
|
+
function loadMcpConfig(dir) {
|
|
1541
|
+
const searchPaths = [
|
|
1542
|
+
dir ? join3(dir, ".mcp.json") : null,
|
|
1543
|
+
join3(process.cwd(), ".mcp.json"),
|
|
1544
|
+
join3(process.env.HOME ?? "", ".mcp.json")
|
|
1545
|
+
].filter(Boolean);
|
|
1546
|
+
for (const p of searchPaths) {
|
|
1547
|
+
if (existsSync3(p)) {
|
|
1548
|
+
try {
|
|
1549
|
+
return JSON.parse(readFileSync4(p, "utf-8"));
|
|
1550
|
+
} catch {
|
|
1551
|
+
continue;
|
|
1552
|
+
}
|
|
2150
1553
|
}
|
|
2151
1554
|
}
|
|
1555
|
+
return null;
|
|
2152
1556
|
}
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
const c = await ask(chalk12.cyan(" \u276F "));
|
|
2176
|
-
const ci = parseInt(c);
|
|
2177
|
-
if (ci === 1) {
|
|
2178
|
-
const name = await ask(chalk12.white(" \uC774\uB984: "));
|
|
2179
|
-
const url = await ask(chalk12.white(" URL: "));
|
|
2180
|
-
const email = await ask(chalk12.white(" \uC774\uBA54\uC77C (\uC120\uD0DD): "));
|
|
2181
|
-
const desc = await ask(chalk12.white(" \uC124\uBA85 (\uC120\uD0DD): "));
|
|
2182
|
-
if (name && url) {
|
|
2183
|
-
const id = name.toLowerCase().replace(/[^a-z0-9]/g, "-");
|
|
2184
|
-
addEnvironment({ id, name, url: url.replace(/\/+$/, ""), email: email || void 0, description: desc || void 0 });
|
|
2185
|
-
console.log(chalk12.green(`
|
|
2186
|
-
\u2713 ${name} \uCD94\uAC00\uB428
|
|
2187
|
-
`));
|
|
2188
|
-
}
|
|
2189
|
-
} else if (ci === 2) {
|
|
2190
|
-
const presets = [
|
|
2191
|
-
{ id: "hq", name: "\uBCF8\uC0AC (244)", url: "https://xgen.x2bee.com", email: "admin@plateer.com", description: "\uBCF8\uC0AC \uBC30\uD3EC \uD658\uACBD" },
|
|
2192
|
-
{ id: "jeju", name: "\uC81C\uC8FC (243)", url: "https://jeju-xgen.x2bee.com", email: "admin@plateer.com", description: "\uC81C\uC8FC \uC11C\uBC84" },
|
|
2193
|
-
{ id: "lotte", name: "\uB86F\uB370\uBAB0 (DGX)", url: "https://lotteimall-xgen.x2bee.com", description: "\uB86F\uB370\uBAB0 DGX Spark" }
|
|
2194
|
-
];
|
|
2195
|
-
console.log(chalk12.bold("\n \uAE30\uBCF8 \uD658\uACBD \uD504\uB9AC\uC14B:\n"));
|
|
2196
|
-
presets.forEach((p, i) => {
|
|
2197
|
-
console.log(` ${chalk12.cyan(`${i + 1}.`)} ${p.name} ${chalk12.gray(p.url)}`);
|
|
2198
|
-
});
|
|
2199
|
-
console.log(` ${chalk12.cyan(`${presets.length + 1}.`)} \uC804\uBD80 \uB4F1\uB85D`);
|
|
2200
|
-
console.log();
|
|
2201
|
-
const pc = await ask(chalk12.cyan(" \u276F "));
|
|
2202
|
-
const pi = parseInt(pc);
|
|
2203
|
-
if (pi === presets.length + 1) {
|
|
2204
|
-
for (const p of presets) addEnvironment(p);
|
|
2205
|
-
console.log(chalk12.green(` \u2713 ${presets.length}\uAC1C \uD658\uACBD \uB4F1\uB85D\uB428
|
|
2206
|
-
`));
|
|
2207
|
-
} else if (pi >= 1 && pi <= presets.length) {
|
|
2208
|
-
addEnvironment(presets[pi - 1]);
|
|
2209
|
-
console.log(chalk12.green(` \u2713 ${presets[pi - 1].name} \uB4F1\uB85D\uB428
|
|
2210
|
-
`));
|
|
2211
|
-
}
|
|
2212
|
-
} else if (opts[ci - 1] === "\uD658\uACBD \uC804\uD658 + \uB85C\uADF8\uC778") {
|
|
2213
|
-
console.log();
|
|
2214
|
-
envs.forEach((e, i) => {
|
|
2215
|
-
const mark = e.id === active?.id ? chalk12.green("\u25CF ") : " ";
|
|
2216
|
-
console.log(` ${mark}${chalk12.cyan(`${i + 1}.`)} ${e.name} ${chalk12.gray(e.url)}`);
|
|
2217
|
-
});
|
|
2218
|
-
console.log();
|
|
2219
|
-
const ei = parseInt(await ask(chalk12.cyan(" \u276F "))) - 1;
|
|
2220
|
-
if (ei >= 0 && ei < envs.length) {
|
|
2221
|
-
switchEnvironment(envs[ei].id);
|
|
2222
|
-
console.log(chalk12.green(`
|
|
2223
|
-
\u2713 ${envs[ei].name} \uC804\uD658\uB428 \u2192 ${envs[ei].url}`));
|
|
2224
|
-
if (envs[ei].email) {
|
|
2225
|
-
const pw = await ask(chalk12.white(` \uBE44\uBC00\uBC88\uD638 (${envs[ei].email}): `));
|
|
2226
|
-
if (pw) {
|
|
1557
|
+
var McpClient, McpManager;
|
|
1558
|
+
var init_client2 = __esm({
|
|
1559
|
+
"src/mcp/client.ts"() {
|
|
1560
|
+
"use strict";
|
|
1561
|
+
McpClient = class {
|
|
1562
|
+
process = null;
|
|
1563
|
+
requestId = 0;
|
|
1564
|
+
pending = /* @__PURE__ */ new Map();
|
|
1565
|
+
serverName;
|
|
1566
|
+
config;
|
|
1567
|
+
tools = [];
|
|
1568
|
+
constructor(serverName, config) {
|
|
1569
|
+
this.serverName = serverName;
|
|
1570
|
+
this.config = config;
|
|
1571
|
+
}
|
|
1572
|
+
async start() {
|
|
1573
|
+
this.process = spawn(this.config.command, this.config.args ?? [], {
|
|
1574
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
1575
|
+
env: { ...process.env, ...this.config.env }
|
|
1576
|
+
});
|
|
1577
|
+
const rl = createInterface4({ input: this.process.stdout });
|
|
1578
|
+
rl.on("line", (line) => {
|
|
2227
1579
|
try {
|
|
2228
|
-
const
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
1580
|
+
const msg = JSON.parse(line);
|
|
1581
|
+
if (msg.id !== void 0 && this.pending.has(msg.id)) {
|
|
1582
|
+
const p = this.pending.get(msg.id);
|
|
1583
|
+
this.pending.delete(msg.id);
|
|
1584
|
+
if (msg.error) {
|
|
1585
|
+
p.reject(new Error(msg.error.message));
|
|
1586
|
+
} else {
|
|
1587
|
+
p.resolve(msg.result);
|
|
1588
|
+
}
|
|
1589
|
+
}
|
|
1590
|
+
} catch {
|
|
1591
|
+
}
|
|
1592
|
+
});
|
|
1593
|
+
this.process.on("error", (err) => {
|
|
1594
|
+
console.error(`MCP [${this.serverName}] \uD504\uB85C\uC138\uC2A4 \uC624\uB958:`, err.message);
|
|
1595
|
+
});
|
|
1596
|
+
await this.send("initialize", {
|
|
1597
|
+
protocolVersion: "2024-11-05",
|
|
1598
|
+
capabilities: {},
|
|
1599
|
+
clientInfo: { name: "open-xgen", version: "0.3.0" }
|
|
1600
|
+
});
|
|
1601
|
+
await this.send("notifications/initialized", {});
|
|
1602
|
+
}
|
|
1603
|
+
send(method, params) {
|
|
1604
|
+
return new Promise((resolve, reject) => {
|
|
1605
|
+
const id = ++this.requestId;
|
|
1606
|
+
const request = { jsonrpc: "2.0", id, method, params };
|
|
1607
|
+
this.pending.set(id, { resolve, reject });
|
|
1608
|
+
const timeout = setTimeout(() => {
|
|
1609
|
+
this.pending.delete(id);
|
|
1610
|
+
reject(new Error(`MCP \uC694\uCCAD \uD0C0\uC784\uC544\uC6C3: ${method}`));
|
|
1611
|
+
}, 15e3);
|
|
1612
|
+
this.pending.set(id, {
|
|
1613
|
+
resolve: (v) => {
|
|
1614
|
+
clearTimeout(timeout);
|
|
1615
|
+
resolve(v);
|
|
1616
|
+
},
|
|
1617
|
+
reject: (e) => {
|
|
1618
|
+
clearTimeout(timeout);
|
|
1619
|
+
reject(e);
|
|
2238
1620
|
}
|
|
1621
|
+
});
|
|
1622
|
+
this.process?.stdin?.write(JSON.stringify(request) + "\n");
|
|
1623
|
+
});
|
|
1624
|
+
}
|
|
1625
|
+
async listTools() {
|
|
1626
|
+
const result = await this.send("tools/list", {});
|
|
1627
|
+
this.tools = result.tools ?? [];
|
|
1628
|
+
return this.tools;
|
|
1629
|
+
}
|
|
1630
|
+
async callTool(name, args) {
|
|
1631
|
+
const result = await this.send("tools/call", { name, arguments: args });
|
|
1632
|
+
return result.content?.map((c) => c.text ?? "").join("\n") ?? "";
|
|
1633
|
+
}
|
|
1634
|
+
getOpenAITools() {
|
|
1635
|
+
return this.tools.map((t) => ({
|
|
1636
|
+
type: "function",
|
|
1637
|
+
function: {
|
|
1638
|
+
name: `mcp_${this.serverName}_${t.name}`,
|
|
1639
|
+
description: `[MCP:${this.serverName}] ${t.description ?? t.name}`,
|
|
1640
|
+
parameters: t.inputSchema ?? { type: "object", properties: {} }
|
|
1641
|
+
}
|
|
1642
|
+
}));
|
|
1643
|
+
}
|
|
1644
|
+
stop() {
|
|
1645
|
+
this.process?.kill();
|
|
1646
|
+
this.process = null;
|
|
1647
|
+
}
|
|
1648
|
+
};
|
|
1649
|
+
McpManager = class {
|
|
1650
|
+
clients = /* @__PURE__ */ new Map();
|
|
1651
|
+
async startAll(config) {
|
|
1652
|
+
for (const [name, serverConfig] of Object.entries(config.mcpServers)) {
|
|
1653
|
+
if (serverConfig.type !== "stdio") continue;
|
|
1654
|
+
try {
|
|
1655
|
+
const client2 = new McpClient(name, serverConfig);
|
|
1656
|
+
await client2.start();
|
|
1657
|
+
await client2.listTools();
|
|
1658
|
+
this.clients.set(name, client2);
|
|
2239
1659
|
} catch (err) {
|
|
2240
|
-
console.
|
|
2241
|
-
`));
|
|
1660
|
+
console.error(`MCP [${name}] \uC2DC\uC791 \uC2E4\uD328:`, err.message);
|
|
2242
1661
|
}
|
|
2243
1662
|
}
|
|
2244
1663
|
}
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
}
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
1664
|
+
getAllTools() {
|
|
1665
|
+
const tools2 = [];
|
|
1666
|
+
for (const client2 of this.clients.values()) {
|
|
1667
|
+
tools2.push(...client2.getOpenAITools());
|
|
1668
|
+
}
|
|
1669
|
+
return tools2;
|
|
1670
|
+
}
|
|
1671
|
+
async callTool(fullName, args) {
|
|
1672
|
+
const parts = fullName.split("_");
|
|
1673
|
+
if (parts.length < 3 || parts[0] !== "mcp") return `Unknown MCP tool: ${fullName}`;
|
|
1674
|
+
const serverName = parts[1];
|
|
1675
|
+
const toolName = parts.slice(2).join("_");
|
|
1676
|
+
const client2 = this.clients.get(serverName);
|
|
1677
|
+
if (!client2) return `MCP \uC11C\uBC84\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${serverName}`;
|
|
1678
|
+
return client2.callTool(toolName, args);
|
|
1679
|
+
}
|
|
1680
|
+
isMcpTool(name) {
|
|
1681
|
+
return name.startsWith("mcp_");
|
|
1682
|
+
}
|
|
1683
|
+
stopAll() {
|
|
1684
|
+
for (const client2 of this.clients.values()) {
|
|
1685
|
+
client2.stop();
|
|
1686
|
+
}
|
|
1687
|
+
this.clients.clear();
|
|
1688
|
+
}
|
|
1689
|
+
get serverCount() {
|
|
1690
|
+
return this.clients.size;
|
|
1691
|
+
}
|
|
1692
|
+
getServerNames() {
|
|
1693
|
+
return [...this.clients.keys()];
|
|
1694
|
+
}
|
|
1695
|
+
};
|
|
2267
1696
|
}
|
|
2268
1697
|
});
|
|
2269
1698
|
|
|
2270
1699
|
// src/commands/agent.ts
|
|
2271
|
-
import
|
|
1700
|
+
import chalk12 from "chalk";
|
|
2272
1701
|
import { createInterface as createInterface5 } from "readline";
|
|
1702
|
+
function buildSystemPrompt() {
|
|
1703
|
+
const server = getServer();
|
|
1704
|
+
const auth = getAuth();
|
|
1705
|
+
const env = getActiveEnvironment();
|
|
1706
|
+
let prompt2 = `You are OPEN XGEN, an AI assistant in the user's terminal.
|
|
1707
|
+
You combine AI coding capabilities with the XGEN workflow platform.
|
|
1708
|
+
|
|
1709
|
+
## Capabilities
|
|
1710
|
+
1. **Coding**: Read/write files, execute commands, search code, run sandboxed code (JS/TS/Python)
|
|
1711
|
+
2. **XGEN Platform**: List/run workflows, manage documents, query ontology (GraphRAG)
|
|
1712
|
+
|
|
1713
|
+
## Rules
|
|
1714
|
+
- Respond in the same language as the user
|
|
1715
|
+
- Be concise. Show what you did, not how.
|
|
1716
|
+
- When using tools, briefly describe what you're doing
|
|
1717
|
+
- For XGEN operations, use the xgen_* tools`;
|
|
1718
|
+
if (server && auth) {
|
|
1719
|
+
prompt2 += `
|
|
1720
|
+
|
|
1721
|
+
## XGEN Server Connected
|
|
1722
|
+
- Server: ${server}
|
|
1723
|
+
- User: ${auth.username} (ID: ${auth.userId})
|
|
1724
|
+
- Environment: ${env?.name ?? "default"}
|
|
1725
|
+
You can use xgen_workflow_list, xgen_workflow_run, xgen_doc_list, xgen_ontology_query, etc.`;
|
|
1726
|
+
} else {
|
|
1727
|
+
prompt2 += `
|
|
1728
|
+
|
|
1729
|
+
## XGEN Server: Not connected
|
|
1730
|
+
Tell the user to run /connect to connect to an XGEN server.`;
|
|
1731
|
+
}
|
|
1732
|
+
return prompt2;
|
|
1733
|
+
}
|
|
2273
1734
|
async function agentRepl() {
|
|
2274
1735
|
let provider = getDefaultProvider();
|
|
2275
1736
|
if (!provider) {
|
|
2276
1737
|
provider = await guidedProviderSetup();
|
|
2277
|
-
if (!provider)
|
|
2278
|
-
process.exit(1);
|
|
2279
|
-
}
|
|
1738
|
+
if (!provider) process.exit(1);
|
|
2280
1739
|
}
|
|
2281
1740
|
const client2 = createLLMClient(provider);
|
|
2282
|
-
const
|
|
2283
|
-
const
|
|
2284
|
-
const allToolNames = [...getToolNames()];
|
|
1741
|
+
const allTools = [...getAllToolDefs(), ...definitions];
|
|
1742
|
+
const builtinNames = getToolNames();
|
|
2285
1743
|
const mcpConfig = loadMcpConfig();
|
|
2286
1744
|
if (mcpConfig && Object.keys(mcpConfig.mcpServers).length > 0) {
|
|
2287
1745
|
mcpManager = new McpManager();
|
|
2288
1746
|
try {
|
|
2289
1747
|
await mcpManager.startAll(mcpConfig);
|
|
2290
|
-
if (mcpManager.serverCount > 0)
|
|
2291
|
-
const mcpTools = mcpManager.getAllTools();
|
|
2292
|
-
allTools.push(...mcpTools);
|
|
2293
|
-
allToolNames.push(...mcpTools.map((t) => t.function.name));
|
|
2294
|
-
}
|
|
1748
|
+
if (mcpManager.serverCount > 0) allTools.push(...mcpManager.getAllTools());
|
|
2295
1749
|
} catch {
|
|
2296
1750
|
}
|
|
2297
1751
|
}
|
|
2298
|
-
const messages = [{ role: "system", content:
|
|
2299
|
-
console.log();
|
|
2300
|
-
console.log(box([
|
|
2301
|
-
`${chalk13.bold("OPEN XGEN Agent")}`,
|
|
2302
|
-
``,
|
|
2303
|
-
`${chalk13.gray("\uD504\uB85C\uBC14\uC774\uB354")} ${provider.name} ${chalk13.gray("\xB7")} ${provider.model}`,
|
|
2304
|
-
`${chalk13.gray("\uB3C4\uAD6C")} ${getToolNames().length}\uAC1C \uB0B4\uC7A5${mcpManager && mcpManager.serverCount > 0 ? ` + ${mcpManager.getAllTools().length}\uAC1C MCP` : ""}`,
|
|
2305
|
-
``,
|
|
2306
|
-
`${chalk13.gray("\uBB34\uC5C7\uC774\uB4E0 \uBB3C\uC5B4\uBCF4\uC138\uC694. \uD30C\uC77C \uC77D\uAE30/\uC4F0\uAE30, \uCF54\uB4DC \uC2E4\uD589, \uAC80\uC0C9 \uAC00\uB2A5.")}`,
|
|
2307
|
-
`${chalk13.gray("/help \uB3C4\uC6C0\uB9D0 \xB7 /home \uD648 \xB7 /exit \uC885\uB8CC")}`
|
|
2308
|
-
]));
|
|
1752
|
+
const messages = [{ role: "system", content: buildSystemPrompt() }];
|
|
1753
|
+
console.log(welcome());
|
|
2309
1754
|
console.log();
|
|
1755
|
+
const server = getServer();
|
|
1756
|
+
const auth = getAuth();
|
|
1757
|
+
const env = getActiveEnvironment();
|
|
1758
|
+
console.log(chalk12.gray(` ${provider.name} \xB7 ${provider.model}`));
|
|
1759
|
+
if (server && auth) {
|
|
1760
|
+
console.log(chalk12.gray(` ${env?.name ?? "XGEN"} \xB7 ${auth.username}@${server.replace("https://", "")}`));
|
|
1761
|
+
}
|
|
1762
|
+
console.log(chalk12.gray(` ${builtinNames.length} \uB3C4\uAD6C + ${definitions.length} XGEN${mcpManager?.serverCount ? ` + ${mcpManager.getAllTools().length} MCP` : ""}`));
|
|
1763
|
+
console.log(chalk12.gray(` /help \xB7 /connect \xB7 /env \xB7 /provider \xB7 /exit
|
|
1764
|
+
`));
|
|
2310
1765
|
const rl = createInterface5({ input: process.stdin, output: process.stdout });
|
|
2311
|
-
const askUser = () => new Promise((resolve) => rl.question(
|
|
1766
|
+
const askUser = () => new Promise((resolve) => rl.question(chalk12.cyan(" \u276F "), (a) => resolve(a.trim())));
|
|
2312
1767
|
process.on("SIGINT", () => {
|
|
2313
|
-
console.log(
|
|
1768
|
+
console.log(chalk12.gray("\n \u{1F44B}\n"));
|
|
2314
1769
|
mcpManager?.stopAll();
|
|
2315
1770
|
rl.close();
|
|
2316
1771
|
process.exit(0);
|
|
@@ -2318,104 +1773,95 @@ async function agentRepl() {
|
|
|
2318
1773
|
while (true) {
|
|
2319
1774
|
const input = await askUser();
|
|
2320
1775
|
if (!input) continue;
|
|
2321
|
-
if (input === "exit" || input === "
|
|
2322
|
-
console.log(
|
|
1776
|
+
if (input === "/exit" || input === "exit") {
|
|
1777
|
+
console.log(chalk12.gray("\n \u{1F44B}\n"));
|
|
2323
1778
|
mcpManager?.stopAll();
|
|
2324
1779
|
rl.close();
|
|
2325
1780
|
break;
|
|
2326
1781
|
}
|
|
2327
1782
|
if (input === "/help") {
|
|
2328
|
-
console.log(
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
console.log();
|
|
1783
|
+
console.log(`
|
|
1784
|
+
${chalk12.bold("\uC2AC\uB798\uC2DC \uCEE4\uB9E8\uB4DC")}
|
|
1785
|
+
${chalk12.cyan("/connect")} XGEN \uC11C\uBC84 \uC5F0\uACB0 + \uB85C\uADF8\uC778
|
|
1786
|
+
${chalk12.cyan("/env")} \uD658\uACBD \uC804\uD658 (\uBCF8\uC0AC/\uC81C\uC8FC/\uB86F\uB370\uBAB0)
|
|
1787
|
+
${chalk12.cyan("/provider")} \uD504\uB85C\uBC14\uC774\uB354 \uBCC0\uACBD
|
|
1788
|
+
${chalk12.cyan("/tools")} \uC0AC\uC6A9 \uAC00\uB2A5\uD55C \uB3C4\uAD6C \uBAA9\uB85D
|
|
1789
|
+
${chalk12.cyan("/status")} \uD604\uC7AC \uC5F0\uACB0 \uC0C1\uD0DC
|
|
1790
|
+
${chalk12.cyan("/clear")} \uB300\uD654 \uCD08\uAE30\uD654
|
|
1791
|
+
${chalk12.cyan("/exit")} \uC885\uB8CC
|
|
1792
|
+
`);
|
|
2339
1793
|
continue;
|
|
2340
1794
|
}
|
|
2341
1795
|
if (input === "/clear") {
|
|
2342
|
-
messages.length =
|
|
2343
|
-
|
|
1796
|
+
messages.length = 0;
|
|
1797
|
+
messages.push({ role: "system", content: buildSystemPrompt() });
|
|
1798
|
+
console.log(chalk12.gray(" \uB300\uD654 \uCD08\uAE30\uD654\uB428.\n"));
|
|
2344
1799
|
continue;
|
|
2345
1800
|
}
|
|
2346
|
-
if (input === "/
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
1801
|
+
if (input === "/status") {
|
|
1802
|
+
const p = getDefaultProvider();
|
|
1803
|
+
const s = getServer();
|
|
1804
|
+
const a = getAuth();
|
|
1805
|
+
const e = getActiveEnvironment();
|
|
1806
|
+
console.log();
|
|
1807
|
+
console.log(` ${chalk12.bold("\uD504\uB85C\uBC14\uC774\uB354")} ${p ? `${p.name} \xB7 ${p.model}` : chalk12.red("\uBBF8\uC124\uC815")}`);
|
|
1808
|
+
console.log(` ${chalk12.bold("\uC11C\uBC84")} ${s && a ? `${a.username}@${s.replace("https://", "")}` : chalk12.red("\uBBF8\uC5F0\uACB0")}`);
|
|
1809
|
+
console.log(` ${chalk12.bold("\uD658\uACBD")} ${e?.name ?? "\uC5C6\uC74C"} (${getEnvironments().length}\uAC1C \uB4F1\uB85D)`);
|
|
1810
|
+
if (mcpManager?.serverCount) {
|
|
1811
|
+
console.log(` ${chalk12.bold("MCP")} ${mcpManager.getServerNames().join(", ")}`);
|
|
2350
1812
|
}
|
|
2351
1813
|
console.log();
|
|
2352
1814
|
continue;
|
|
2353
1815
|
}
|
|
2354
|
-
if (input === "/
|
|
2355
|
-
console.log(
|
|
2356
|
-
|
|
2357
|
-
`));
|
|
1816
|
+
if (input === "/tools") {
|
|
1817
|
+
console.log(`
|
|
1818
|
+
${chalk12.bold("\uCF54\uB529")} ${builtinNames.join(", ")}`);
|
|
1819
|
+
console.log(` ${chalk12.bold("XGEN")} ${definitions.map((t) => t.function.name).join(", ")}`);
|
|
1820
|
+
if (mcpManager?.serverCount) {
|
|
1821
|
+
console.log(` ${chalk12.bold("MCP")} ${mcpManager.getAllTools().map((t) => t.function.name).join(", ")}`);
|
|
1822
|
+
}
|
|
1823
|
+
console.log();
|
|
2358
1824
|
continue;
|
|
2359
1825
|
}
|
|
2360
|
-
if (input === "/
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
if (all.length > 0) {
|
|
2364
|
-
console.log(chalk13.bold("\n \uB4F1\uB85D\uB41C \uD504\uB85C\uBC14\uC774\uB354:\n"));
|
|
2365
|
-
all.forEach((p, i) => {
|
|
2366
|
-
const mark = p.id === provider.id ? chalk13.green("\u25CF ") : " ";
|
|
2367
|
-
console.log(` ${mark}${i + 1}) ${p.name} (${p.model})`);
|
|
2368
|
-
});
|
|
2369
|
-
console.log(chalk13.gray("\n \uBCC0\uACBD\uD558\uB824\uBA74 exit \uD6C4 xgen provider use <id>\n"));
|
|
2370
|
-
}
|
|
1826
|
+
if (input === "/connect") {
|
|
1827
|
+
await connectServer();
|
|
1828
|
+
messages[0] = { role: "system", content: buildSystemPrompt() };
|
|
2371
1829
|
continue;
|
|
2372
1830
|
}
|
|
2373
|
-
if (input === "/
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
const { homeMenu: homeMenu2 } = await Promise.resolve().then(() => (init_home(), home_exports));
|
|
2378
|
-
await homeMenu2();
|
|
2379
|
-
return;
|
|
1831
|
+
if (input === "/env") {
|
|
1832
|
+
await switchEnv();
|
|
1833
|
+
messages[0] = { role: "system", content: buildSystemPrompt() };
|
|
1834
|
+
continue;
|
|
2380
1835
|
}
|
|
2381
|
-
if (input === "/
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
} else {
|
|
2386
|
-
console.log(chalk13.gray("MCP \uC11C\uBC84 \uC5C6\uC74C. .mcp.json\uC744 \uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8\uC5D0 \uCD94\uAC00\uD558\uC138\uC694."));
|
|
2387
|
-
}
|
|
2388
|
-
console.log();
|
|
1836
|
+
if (input === "/provider") {
|
|
1837
|
+
const { guidedProviderSetup: setup } = await Promise.resolve().then(() => (init_provider(), provider_exports));
|
|
1838
|
+
await setup();
|
|
1839
|
+
console.log(chalk12.gray(" \uD504\uB85C\uBC14\uC774\uB354 \uBCC0\uACBD\uB428. /exit \uD6C4 \uC7AC\uC2DC\uC791\uD558\uC138\uC694.\n"));
|
|
2389
1840
|
continue;
|
|
2390
1841
|
}
|
|
2391
1842
|
messages.push({ role: "user", content: input });
|
|
2392
1843
|
try {
|
|
2393
|
-
await
|
|
1844
|
+
await runLoop(client2, provider.model, messages, allTools);
|
|
2394
1845
|
} catch (err) {
|
|
2395
|
-
console.log(
|
|
2396
|
-
\uC624\uB958: ${err.message}
|
|
1846
|
+
console.log(chalk12.red(`
|
|
1847
|
+
\uC624\uB958: ${err.message}
|
|
2397
1848
|
`));
|
|
2398
1849
|
}
|
|
2399
1850
|
}
|
|
2400
1851
|
}
|
|
2401
|
-
async function
|
|
2402
|
-
|
|
2403
|
-
for (let i = 0; i < MAX_ITERATIONS; i++) {
|
|
1852
|
+
async function runLoop(client2, model, messages, tools2) {
|
|
1853
|
+
for (let i = 0; i < 20; i++) {
|
|
2404
1854
|
let first = true;
|
|
2405
1855
|
const result = await streamChat(client2, model, messages, tools2, (delta) => {
|
|
2406
1856
|
if (first) {
|
|
2407
|
-
process.stdout.write(
|
|
1857
|
+
process.stdout.write(chalk12.green("\n ") + "");
|
|
2408
1858
|
first = false;
|
|
2409
1859
|
}
|
|
2410
1860
|
process.stdout.write(delta);
|
|
2411
1861
|
});
|
|
2412
|
-
if (result.content)
|
|
2413
|
-
process.stdout.write("\n\n");
|
|
2414
|
-
}
|
|
1862
|
+
if (result.content) process.stdout.write("\n\n");
|
|
2415
1863
|
if (result.toolCalls.length === 0) {
|
|
2416
|
-
if (result.content) {
|
|
2417
|
-
messages.push({ role: "assistant", content: result.content });
|
|
2418
|
-
}
|
|
1864
|
+
if (result.content) messages.push({ role: "assistant", content: result.content });
|
|
2419
1865
|
return;
|
|
2420
1866
|
}
|
|
2421
1867
|
messages.push({
|
|
@@ -2434,60 +1880,440 @@ async function runAgentLoop(client2, model, messages, tools2) {
|
|
|
2434
1880
|
} catch {
|
|
2435
1881
|
args = {};
|
|
2436
1882
|
}
|
|
2437
|
-
|
|
1883
|
+
const shortArgs = Object.entries(args).map(([k, v]) => {
|
|
1884
|
+
const s = String(v);
|
|
1885
|
+
return `${k}=${s.length > 30 ? s.slice(0, 30) + "\u2026" : s}`;
|
|
1886
|
+
}).join(" ");
|
|
1887
|
+
console.log(chalk12.gray(` \u2699 ${chalk12.white(tc.name)} ${shortArgs}`));
|
|
2438
1888
|
let toolResult;
|
|
2439
|
-
if (
|
|
1889
|
+
if (isXgenTool(tc.name)) {
|
|
1890
|
+
toolResult = await execute8(tc.name, args);
|
|
1891
|
+
} else if (mcpManager?.isMcpTool(tc.name)) {
|
|
2440
1892
|
toolResult = await mcpManager.callTool(tc.name, args);
|
|
2441
1893
|
} else {
|
|
2442
1894
|
toolResult = await executeTool(tc.name, args);
|
|
2443
1895
|
}
|
|
2444
|
-
const truncated = toolResult.length > 4e3 ? toolResult.slice(0, 4e3) + "\n
|
|
2445
|
-
messages.push({
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
1896
|
+
const truncated = toolResult.length > 4e3 ? toolResult.slice(0, 4e3) + "\n\u2026(truncated)" : toolResult;
|
|
1897
|
+
messages.push({ role: "tool", tool_call_id: tc.id, content: truncated });
|
|
1898
|
+
}
|
|
1899
|
+
}
|
|
1900
|
+
console.log(chalk12.yellow("\n \uCD5C\uB300 \uBC18\uBCF5 \uD69F\uC218 \uB3C4\uB2EC.\n"));
|
|
1901
|
+
}
|
|
1902
|
+
async function connectServer() {
|
|
1903
|
+
const { setServer: setServer2, setAuth: setAuth2 } = await Promise.resolve().then(() => (init_store(), store_exports));
|
|
1904
|
+
const { addEnvironment: addEnvironment2 } = await Promise.resolve().then(() => (init_store(), store_exports));
|
|
1905
|
+
console.log(chalk12.bold("\n XGEN \uC11C\uBC84 \uC5F0\uACB0\n"));
|
|
1906
|
+
const presets = [
|
|
1907
|
+
{ id: "hq", name: "\uBCF8\uC0AC", url: "https://xgen.x2bee.com", email: "admin@plateer.com" },
|
|
1908
|
+
{ id: "jeju", name: "\uC81C\uC8FC", url: "https://jeju-xgen.x2bee.com", email: "admin@plateer.com" },
|
|
1909
|
+
{ id: "lotte", name: "\uB86F\uB370\uBAB0", url: "https://lotteimall-xgen.x2bee.com" }
|
|
1910
|
+
];
|
|
1911
|
+
presets.forEach((p, i) => console.log(` ${chalk12.cyan(`${i + 1}.`)} ${p.name} ${chalk12.gray(p.url)}`));
|
|
1912
|
+
console.log(` ${chalk12.cyan("4.")} \uC9C1\uC811 \uC785\uB825`);
|
|
1913
|
+
console.log();
|
|
1914
|
+
const choice = await ask(chalk12.cyan(" \u276F "));
|
|
1915
|
+
let url;
|
|
1916
|
+
let email;
|
|
1917
|
+
const ci = parseInt(choice) - 1;
|
|
1918
|
+
if (ci >= 0 && ci < presets.length) {
|
|
1919
|
+
url = presets[ci].url;
|
|
1920
|
+
email = presets[ci].email;
|
|
1921
|
+
addEnvironment2({ ...presets[ci], description: presets[ci].name });
|
|
1922
|
+
} else {
|
|
1923
|
+
url = await ask(chalk12.white(" URL: "));
|
|
1924
|
+
if (!url) return;
|
|
1925
|
+
}
|
|
1926
|
+
setServer2(url);
|
|
1927
|
+
console.log(chalk12.green(` \u2713 ${url}
|
|
1928
|
+
`));
|
|
1929
|
+
const inputEmail = email || await ask(chalk12.white(" \uC774\uBA54\uC77C: "));
|
|
1930
|
+
const pw = await ask(chalk12.white(" \uBE44\uBC00\uBC88\uD638: "));
|
|
1931
|
+
if (!inputEmail || !pw) return;
|
|
1932
|
+
try {
|
|
1933
|
+
const { apiLogin: apiLogin2 } = await Promise.resolve().then(() => (init_auth(), auth_exports));
|
|
1934
|
+
const result = await apiLogin2(inputEmail, pw);
|
|
1935
|
+
if (result.success && result.access_token) {
|
|
1936
|
+
setAuth2({ accessToken: result.access_token, refreshToken: result.refresh_token ?? "", userId: result.user_id ?? "", username: result.username ?? "", isAdmin: false, expiresAt: null });
|
|
1937
|
+
console.log(chalk12.green(` \u2713 ${result.username} \uB85C\uADF8\uC778\uB428
|
|
1938
|
+
`));
|
|
1939
|
+
} else {
|
|
1940
|
+
console.log(chalk12.red(` \u2717 ${result.message}
|
|
1941
|
+
`));
|
|
2450
1942
|
}
|
|
1943
|
+
} catch (err) {
|
|
1944
|
+
console.log(chalk12.red(` \u2717 ${err.message}
|
|
1945
|
+
`));
|
|
2451
1946
|
}
|
|
2452
|
-
console.log(chalk13.yellow("\n\uCD5C\uB300 \uBC18\uBCF5 \uD69F\uC218\uC5D0 \uB3C4\uB2EC\uD588\uC2B5\uB2C8\uB2E4.\n"));
|
|
2453
1947
|
}
|
|
2454
|
-
function
|
|
2455
|
-
const
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
1948
|
+
async function switchEnv() {
|
|
1949
|
+
const { getEnvironments: getEnvs, switchEnvironment: switchEnvironment2 } = await Promise.resolve().then(() => (init_store(), store_exports));
|
|
1950
|
+
const envs = getEnvs();
|
|
1951
|
+
if (!envs.length) {
|
|
1952
|
+
console.log(chalk12.gray("\n \uD658\uACBD \uC5C6\uC74C. /connect\uB85C \uBA3C\uC800 \uC5F0\uACB0\uD558\uC138\uC694.\n"));
|
|
1953
|
+
return;
|
|
1954
|
+
}
|
|
1955
|
+
const active = getActiveEnvironment();
|
|
1956
|
+
console.log();
|
|
1957
|
+
envs.forEach((e, i) => {
|
|
1958
|
+
const mark = e.id === active?.id ? chalk12.green("\u25CF ") : " ";
|
|
1959
|
+
console.log(` ${mark}${chalk12.cyan(`${i + 1}.`)} ${e.name} ${chalk12.gray(e.url)}`);
|
|
1960
|
+
});
|
|
1961
|
+
console.log();
|
|
1962
|
+
const ci = parseInt(await ask(chalk12.cyan(" \u276F "))) - 1;
|
|
1963
|
+
if (ci >= 0 && ci < envs.length) {
|
|
1964
|
+
switchEnvironment2(envs[ci].id);
|
|
1965
|
+
console.log(chalk12.green(` \u2713 ${envs[ci].name}
|
|
1966
|
+
`));
|
|
2459
1967
|
}
|
|
2460
|
-
return parts.join(", ");
|
|
2461
1968
|
}
|
|
2462
1969
|
function registerAgentCommand(program2) {
|
|
2463
|
-
program2.command("agent").description("OPEN XGEN AI \
|
|
1970
|
+
program2.command("agent").description("OPEN XGEN AI \uC5D0\uC774\uC804\uD2B8").action(async () => {
|
|
2464
1971
|
await agentRepl();
|
|
2465
1972
|
});
|
|
2466
1973
|
}
|
|
2467
|
-
var
|
|
1974
|
+
var mcpManager;
|
|
2468
1975
|
var init_agent = __esm({
|
|
2469
1976
|
"src/commands/agent.ts"() {
|
|
2470
1977
|
"use strict";
|
|
2471
1978
|
init_store();
|
|
2472
1979
|
init_llm();
|
|
2473
1980
|
init_tools();
|
|
1981
|
+
init_xgen_api();
|
|
2474
1982
|
init_client2();
|
|
2475
1983
|
init_provider();
|
|
2476
1984
|
init_ui();
|
|
2477
|
-
SYSTEM_PROMPT = `You are OPEN XGEN Agent, an AI coding assistant running in the user's terminal.
|
|
2478
|
-
You have access to tools for reading/writing files, executing commands, searching code, and running sandboxed code.
|
|
2479
|
-
You can also use MCP (Model Context Protocol) tools if available.
|
|
2480
|
-
Always respond in the same language as the user.
|
|
2481
|
-
When using tools, be concise about what you're doing.
|
|
2482
|
-
For file edits, show what you changed briefly.
|
|
2483
|
-
For sandbox_run, you can install npm/pip packages and run isolated code.`;
|
|
2484
1985
|
mcpManager = null;
|
|
2485
1986
|
}
|
|
2486
1987
|
});
|
|
2487
1988
|
|
|
1989
|
+
// src/dashboard/renderer.ts
|
|
1990
|
+
import chalk15 from "chalk";
|
|
1991
|
+
function clearScreen() {
|
|
1992
|
+
process.stdout.write("\x1B[2J\x1B[H");
|
|
1993
|
+
}
|
|
1994
|
+
function renderHeader(activeTab, tabs, env) {
|
|
1995
|
+
const w = W2();
|
|
1996
|
+
const title = chalk15.cyan.bold(" OPEN XGEN ");
|
|
1997
|
+
const envTag = env ? chalk15.gray(` \xB7 ${env}`) : "";
|
|
1998
|
+
const tabBar = tabs.map((t) => {
|
|
1999
|
+
if (t === activeTab) return chalk15.bgCyan.black(` ${t} `);
|
|
2000
|
+
return chalk15.gray(` ${t} `);
|
|
2001
|
+
}).join(chalk15.gray("\u2502"));
|
|
2002
|
+
console.log(chalk15.bgGray.black(" ".repeat(w)));
|
|
2003
|
+
console.log(chalk15.bgGray.black(`${title}${envTag}${" ".repeat(Math.max(0, w - stripAnsi(title + envTag).length))}`));
|
|
2004
|
+
console.log(chalk15.gray("\u2500".repeat(w)));
|
|
2005
|
+
console.log(tabBar);
|
|
2006
|
+
console.log(chalk15.gray("\u2500".repeat(w)));
|
|
2007
|
+
}
|
|
2008
|
+
function renderStatusBar(text) {
|
|
2009
|
+
const w = W2();
|
|
2010
|
+
const padded = ` ${text}${" ".repeat(Math.max(0, w - text.length - 1))}`;
|
|
2011
|
+
console.log(chalk15.gray("\u2500".repeat(w)));
|
|
2012
|
+
console.log(chalk15.bgGray.black(padded));
|
|
2013
|
+
}
|
|
2014
|
+
function renderList(items, selected, title, startRow) {
|
|
2015
|
+
if (title) console.log(chalk15.bold(` ${title}`));
|
|
2016
|
+
console.log();
|
|
2017
|
+
const pageSize = H() - 12;
|
|
2018
|
+
const start = Math.max(0, selected - pageSize + 3);
|
|
2019
|
+
const visible = items.slice(start, start + pageSize);
|
|
2020
|
+
visible.forEach((item, i) => {
|
|
2021
|
+
const idx = start + i;
|
|
2022
|
+
const cursor = idx === selected ? chalk15.cyan("\u25B8 ") : " ";
|
|
2023
|
+
const num = chalk15.gray(`${String(idx + 1).padStart(3)}.`);
|
|
2024
|
+
const tag = item.tag ? ` ${item.tag}` : "";
|
|
2025
|
+
const line = `${cursor}${num} ${item.label}${tag}`;
|
|
2026
|
+
if (idx === selected) {
|
|
2027
|
+
console.log(chalk15.white.bold(line));
|
|
2028
|
+
if (item.detail) console.log(chalk15.gray(` ${item.detail}`));
|
|
2029
|
+
} else {
|
|
2030
|
+
console.log(line);
|
|
2031
|
+
}
|
|
2032
|
+
});
|
|
2033
|
+
if (items.length > pageSize) {
|
|
2034
|
+
console.log(chalk15.gray(`
|
|
2035
|
+
${start + 1}-${Math.min(start + pageSize, items.length)} / ${items.length}`));
|
|
2036
|
+
}
|
|
2037
|
+
}
|
|
2038
|
+
function renderPanel(title, lines) {
|
|
2039
|
+
const w = W2() - 4;
|
|
2040
|
+
console.log(chalk15.cyan(` \u250C${"\u2500".repeat(w)}\u2510`));
|
|
2041
|
+
console.log(chalk15.cyan(` \u2502 ${chalk15.bold(title)}${" ".repeat(Math.max(0, w - stripAnsi(title).length - 1))}\u2502`));
|
|
2042
|
+
console.log(chalk15.cyan(` \u251C${"\u2500".repeat(w)}\u2524`));
|
|
2043
|
+
for (const line of lines) {
|
|
2044
|
+
const clean = stripAnsi(line);
|
|
2045
|
+
const pad = Math.max(0, w - clean.length - 1);
|
|
2046
|
+
console.log(chalk15.cyan(` \u2502 `) + line + " ".repeat(pad) + chalk15.cyan("\u2502"));
|
|
2047
|
+
}
|
|
2048
|
+
console.log(chalk15.cyan(` \u2514${"\u2500".repeat(w)}\u2518`));
|
|
2049
|
+
}
|
|
2050
|
+
function stripAnsi(str) {
|
|
2051
|
+
return str.replace(/\x1b\[[0-9;]*m/g, "");
|
|
2052
|
+
}
|
|
2053
|
+
var W2, H;
|
|
2054
|
+
var init_renderer = __esm({
|
|
2055
|
+
"src/dashboard/renderer.ts"() {
|
|
2056
|
+
"use strict";
|
|
2057
|
+
W2 = () => Math.min(process.stdout.columns || 80, 100);
|
|
2058
|
+
H = () => Math.min(process.stdout.rows || 30, 40);
|
|
2059
|
+
}
|
|
2060
|
+
});
|
|
2061
|
+
|
|
2062
|
+
// src/dashboard/index.ts
|
|
2063
|
+
var dashboard_exports = {};
|
|
2064
|
+
__export(dashboard_exports, {
|
|
2065
|
+
dashboard: () => dashboard
|
|
2066
|
+
});
|
|
2067
|
+
import chalk16 from "chalk";
|
|
2068
|
+
import { createInterface as createInterface7 } from "readline";
|
|
2069
|
+
async function dashboard() {
|
|
2070
|
+
const state = {
|
|
2071
|
+
activeTab: 0,
|
|
2072
|
+
workflows: [],
|
|
2073
|
+
documents: [],
|
|
2074
|
+
selectedIdx: 0
|
|
2075
|
+
};
|
|
2076
|
+
await loadData(state);
|
|
2077
|
+
render(state);
|
|
2078
|
+
const rl = createInterface7({ input: process.stdin, output: process.stdout });
|
|
2079
|
+
if (process.stdin.isTTY) {
|
|
2080
|
+
process.stdin.setRawMode(true);
|
|
2081
|
+
process.stdin.resume();
|
|
2082
|
+
process.stdin.setEncoding("utf8");
|
|
2083
|
+
process.stdin.on("data", async (key) => {
|
|
2084
|
+
if (key === "") {
|
|
2085
|
+
cleanup(rl);
|
|
2086
|
+
process.exit(0);
|
|
2087
|
+
}
|
|
2088
|
+
if (key === " ") {
|
|
2089
|
+
state.activeTab = (state.activeTab + 1) % TABS.length;
|
|
2090
|
+
state.selectedIdx = 0;
|
|
2091
|
+
render(state);
|
|
2092
|
+
return;
|
|
2093
|
+
}
|
|
2094
|
+
if (key === "\x1B[Z") {
|
|
2095
|
+
state.activeTab = (state.activeTab - 1 + TABS.length) % TABS.length;
|
|
2096
|
+
state.selectedIdx = 0;
|
|
2097
|
+
render(state);
|
|
2098
|
+
return;
|
|
2099
|
+
}
|
|
2100
|
+
if (key === "\x1B[A") {
|
|
2101
|
+
state.selectedIdx = Math.max(0, state.selectedIdx - 1);
|
|
2102
|
+
render(state);
|
|
2103
|
+
return;
|
|
2104
|
+
}
|
|
2105
|
+
if (key === "\x1B[B") {
|
|
2106
|
+
const max = getCurrentListLength(state) - 1;
|
|
2107
|
+
state.selectedIdx = Math.min(max, state.selectedIdx + 1);
|
|
2108
|
+
render(state);
|
|
2109
|
+
return;
|
|
2110
|
+
}
|
|
2111
|
+
if (key === "\r") {
|
|
2112
|
+
await handleEnter(state, rl);
|
|
2113
|
+
return;
|
|
2114
|
+
}
|
|
2115
|
+
const num = parseInt(key);
|
|
2116
|
+
if (num >= 1 && num <= 5) {
|
|
2117
|
+
state.activeTab = num - 1;
|
|
2118
|
+
state.selectedIdx = 0;
|
|
2119
|
+
render(state);
|
|
2120
|
+
return;
|
|
2121
|
+
}
|
|
2122
|
+
if (key === "c") {
|
|
2123
|
+
state.activeTab = 0;
|
|
2124
|
+
render(state);
|
|
2125
|
+
return;
|
|
2126
|
+
}
|
|
2127
|
+
if (key === "w") {
|
|
2128
|
+
state.activeTab = 1;
|
|
2129
|
+
render(state);
|
|
2130
|
+
return;
|
|
2131
|
+
}
|
|
2132
|
+
if (key === "d") {
|
|
2133
|
+
state.activeTab = 2;
|
|
2134
|
+
render(state);
|
|
2135
|
+
return;
|
|
2136
|
+
}
|
|
2137
|
+
if (key === "o") {
|
|
2138
|
+
state.activeTab = 3;
|
|
2139
|
+
render(state);
|
|
2140
|
+
return;
|
|
2141
|
+
}
|
|
2142
|
+
if (key === "s") {
|
|
2143
|
+
state.activeTab = 4;
|
|
2144
|
+
render(state);
|
|
2145
|
+
return;
|
|
2146
|
+
}
|
|
2147
|
+
if (key === "r") {
|
|
2148
|
+
await loadData(state);
|
|
2149
|
+
render(state);
|
|
2150
|
+
return;
|
|
2151
|
+
}
|
|
2152
|
+
if (key === "q") {
|
|
2153
|
+
cleanup(rl);
|
|
2154
|
+
process.exit(0);
|
|
2155
|
+
}
|
|
2156
|
+
});
|
|
2157
|
+
} else {
|
|
2158
|
+
cleanup(rl);
|
|
2159
|
+
await agentRepl();
|
|
2160
|
+
}
|
|
2161
|
+
}
|
|
2162
|
+
function render(state) {
|
|
2163
|
+
clearScreen();
|
|
2164
|
+
const env = getActiveEnvironment();
|
|
2165
|
+
const auth = getAuth();
|
|
2166
|
+
const server = getServer();
|
|
2167
|
+
const envLabel = env?.name ?? (server ? server.replace("https://", "") : "\uBBF8\uC5F0\uACB0");
|
|
2168
|
+
const userLabel = auth ? `${auth.username}@${envLabel}` : envLabel;
|
|
2169
|
+
renderHeader(TABS[state.activeTab], TABS, userLabel);
|
|
2170
|
+
console.log();
|
|
2171
|
+
switch (state.activeTab) {
|
|
2172
|
+
case 0:
|
|
2173
|
+
renderChatTab();
|
|
2174
|
+
break;
|
|
2175
|
+
case 1:
|
|
2176
|
+
renderWorkflowTab(state);
|
|
2177
|
+
break;
|
|
2178
|
+
case 2:
|
|
2179
|
+
renderDocTab(state);
|
|
2180
|
+
break;
|
|
2181
|
+
case 3:
|
|
2182
|
+
renderOntologyTab();
|
|
2183
|
+
break;
|
|
2184
|
+
case 4:
|
|
2185
|
+
renderSettingsTab();
|
|
2186
|
+
break;
|
|
2187
|
+
}
|
|
2188
|
+
const provider = getDefaultProvider();
|
|
2189
|
+
const statusText = `${provider?.name ?? "AI \uBBF8\uC124\uC815"} \xB7 ${provider?.model ?? ""} \u2502 Tab:\uC804\uD658 \u2191\u2193:\uC120\uD0DD Enter:\uC2E4\uD589 r:\uC0C8\uB85C\uACE0\uCE68 q:\uC885\uB8CC`;
|
|
2190
|
+
renderStatusBar(statusText);
|
|
2191
|
+
}
|
|
2192
|
+
function renderChatTab() {
|
|
2193
|
+
console.log(chalk16.bold(" AI \uC5D0\uC774\uC804\uD2B8"));
|
|
2194
|
+
console.log();
|
|
2195
|
+
console.log(chalk16.gray(" Enter\uB97C \uB20C\uB7EC AI \uCC44\uD305 \uBAA8\uB4DC\uB85C \uC9C4\uC785\uD569\uB2C8\uB2E4."));
|
|
2196
|
+
console.log(chalk16.gray(" \uCC44\uD305\uC5D0\uC11C \uC6CC\uD06C\uD50C\uB85C\uC6B0 \uC2E4\uD589, \uD30C\uC77C \uD3B8\uC9D1, \uCF54\uB4DC \uC2E4\uD589 \uBAA8\uB450 \uAC00\uB2A5\uD569\uB2C8\uB2E4."));
|
|
2197
|
+
console.log();
|
|
2198
|
+
console.log(chalk16.gray(" \uC608\uC2DC:"));
|
|
2199
|
+
console.log(chalk16.white(' "\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uBAA9\uB85D \uBCF4\uC5EC\uC918"'));
|
|
2200
|
+
console.log(chalk16.white(' "\uC7AC\uC9C1\uC99D\uBA85\uC11C \uC6CC\uD06C\uD50C\uB85C\uC6B0 \uC2E4\uD589\uD574\uC918"'));
|
|
2201
|
+
console.log(chalk16.white(' "\uC774 \uD3F4\uB354\uC5D0 \uC788\uB294 \uD30C\uC77C \uBB50 \uC788\uC5B4?"'));
|
|
2202
|
+
console.log(chalk16.white(' "Python\uC73C\uB85C fibonacci \uD568\uC218 \uB9CC\uB4E4\uC5B4\uC918"'));
|
|
2203
|
+
console.log();
|
|
2204
|
+
}
|
|
2205
|
+
function renderWorkflowTab(state) {
|
|
2206
|
+
if (state.workflows.length === 0) {
|
|
2207
|
+
console.log(chalk16.gray(" \uC11C\uBC84 \uBBF8\uC5F0\uACB0 \uB610\uB294 \uC6CC\uD06C\uD50C\uB85C\uC6B0 \uC5C6\uC74C"));
|
|
2208
|
+
console.log(chalk16.gray(" s\uD0A4 \u2192 \uC124\uC815\uC5D0\uC11C \uC11C\uBC84 \uC5F0\uACB0"));
|
|
2209
|
+
return;
|
|
2210
|
+
}
|
|
2211
|
+
renderList(state.workflows, state.selectedIdx, `\uC6CC\uD06C\uD50C\uB85C\uC6B0 (${state.workflows.length}\uAC1C)`);
|
|
2212
|
+
}
|
|
2213
|
+
function renderDocTab(state) {
|
|
2214
|
+
if (state.documents.length === 0) {
|
|
2215
|
+
console.log(chalk16.gray(" \uC11C\uBC84 \uBBF8\uC5F0\uACB0 \uB610\uB294 \uBB38\uC11C \uC5C6\uC74C"));
|
|
2216
|
+
return;
|
|
2217
|
+
}
|
|
2218
|
+
renderList(state.documents, state.selectedIdx, `\uBB38\uC11C (${state.documents.length}\uAC1C)`);
|
|
2219
|
+
}
|
|
2220
|
+
function renderOntologyTab() {
|
|
2221
|
+
console.log(chalk16.bold(" \uC628\uD1A8\uB85C\uC9C0 (GraphRAG)"));
|
|
2222
|
+
console.log();
|
|
2223
|
+
console.log(chalk16.gray(" Enter\uB97C \uB20C\uB7EC \uC628\uD1A8\uB85C\uC9C0 \uC9C8\uC758 \uBAA8\uB4DC\uB85C \uC9C4\uC785\uD569\uB2C8\uB2E4."));
|
|
2224
|
+
console.log(chalk16.gray(" \uC9C0\uC2DD \uADF8\uB798\uD504 \uAE30\uBC18 \uC9C8\uBB38-\uB2F5\uBCC0\uC744 \uC218\uD589\uD569\uB2C8\uB2E4."));
|
|
2225
|
+
console.log();
|
|
2226
|
+
}
|
|
2227
|
+
function renderSettingsTab() {
|
|
2228
|
+
const provider = getDefaultProvider();
|
|
2229
|
+
const server = getServer();
|
|
2230
|
+
const auth = getAuth();
|
|
2231
|
+
const env = getActiveEnvironment();
|
|
2232
|
+
const lines = [
|
|
2233
|
+
`\uD504\uB85C\uBC14\uC774\uB354: ${provider ? `${provider.name} \xB7 ${provider.model}` : chalk16.red("\uBBF8\uC124\uC815")}`,
|
|
2234
|
+
`\uC11C\uBC84: ${server ?? chalk16.red("\uBBF8\uC5F0\uACB0")}`,
|
|
2235
|
+
`\uC0AC\uC6A9\uC790: ${auth?.username ?? "-"}`,
|
|
2236
|
+
`\uD658\uACBD: ${env?.name ?? "-"}`
|
|
2237
|
+
];
|
|
2238
|
+
renderPanel("\uD604\uC7AC \uC124\uC815", lines);
|
|
2239
|
+
console.log();
|
|
2240
|
+
console.log(chalk16.gray(" Enter \u2192 AI \uCC44\uD305\uC5D0\uC11C /connect, /provider, /env \uC0AC\uC6A9"));
|
|
2241
|
+
}
|
|
2242
|
+
function getCurrentListLength(state) {
|
|
2243
|
+
switch (state.activeTab) {
|
|
2244
|
+
case 1:
|
|
2245
|
+
return state.workflows.length;
|
|
2246
|
+
case 2:
|
|
2247
|
+
return state.documents.length;
|
|
2248
|
+
default:
|
|
2249
|
+
return 0;
|
|
2250
|
+
}
|
|
2251
|
+
}
|
|
2252
|
+
async function handleEnter(state, rl) {
|
|
2253
|
+
if (state.activeTab === 0 || state.activeTab === 3 || state.activeTab === 4) {
|
|
2254
|
+
cleanup(rl);
|
|
2255
|
+
await agentRepl();
|
|
2256
|
+
await dashboard();
|
|
2257
|
+
return;
|
|
2258
|
+
}
|
|
2259
|
+
if (state.activeTab === 1 && state.workflows.length > 0) {
|
|
2260
|
+
const selected = state.workflows[state.selectedIdx];
|
|
2261
|
+
cleanup(rl);
|
|
2262
|
+
console.log(chalk16.green(`
|
|
2263
|
+
\u2713 ${selected.label} \uC120\uD0DD\uB428
|
|
2264
|
+
`));
|
|
2265
|
+
await agentRepl();
|
|
2266
|
+
await dashboard();
|
|
2267
|
+
return;
|
|
2268
|
+
}
|
|
2269
|
+
}
|
|
2270
|
+
async function loadData(state) {
|
|
2271
|
+
const server = getServer();
|
|
2272
|
+
const auth = getAuth();
|
|
2273
|
+
if (!server || !auth) return;
|
|
2274
|
+
try {
|
|
2275
|
+
const { getWorkflowListDetail: getWorkflowListDetail2 } = await Promise.resolve().then(() => (init_workflow(), workflow_exports));
|
|
2276
|
+
const wfs = await getWorkflowListDetail2();
|
|
2277
|
+
state.workflows = wfs.map((w) => {
|
|
2278
|
+
const deployed = w.is_deployed;
|
|
2279
|
+
return {
|
|
2280
|
+
label: w.workflow_name,
|
|
2281
|
+
detail: (w.workflow_id ?? w.id ?? "").toString(),
|
|
2282
|
+
tag: deployed ? chalk16.green("[\uBC30\uD3EC]") : void 0
|
|
2283
|
+
};
|
|
2284
|
+
});
|
|
2285
|
+
} catch {
|
|
2286
|
+
}
|
|
2287
|
+
try {
|
|
2288
|
+
const { listDocuments: listDocuments2 } = await Promise.resolve().then(() => (init_document(), document_exports));
|
|
2289
|
+
const docs = await listDocuments2();
|
|
2290
|
+
state.documents = docs.map((d) => ({
|
|
2291
|
+
label: d.file_name ?? d.name ?? "-",
|
|
2292
|
+
detail: d.file_type ?? "-",
|
|
2293
|
+
tag: d.status ? chalk16.gray(`[${d.status}]`) : void 0
|
|
2294
|
+
}));
|
|
2295
|
+
} catch {
|
|
2296
|
+
}
|
|
2297
|
+
}
|
|
2298
|
+
function cleanup(rl) {
|
|
2299
|
+
if (process.stdin.isTTY) process.stdin.setRawMode(false);
|
|
2300
|
+
rl.close();
|
|
2301
|
+
clearScreen();
|
|
2302
|
+
}
|
|
2303
|
+
var TABS;
|
|
2304
|
+
var init_dashboard = __esm({
|
|
2305
|
+
"src/dashboard/index.ts"() {
|
|
2306
|
+
"use strict";
|
|
2307
|
+
init_renderer();
|
|
2308
|
+
init_store();
|
|
2309
|
+
init_agent();
|
|
2310
|
+
TABS = ["\u{1F4AC} Chat", "\u{1F4CB} Workflows", "\u{1F4C4} Documents", "\u{1F50D} Ontology", "\u2699 Settings"];
|
|
2311
|
+
}
|
|
2312
|
+
});
|
|
2313
|
+
|
|
2488
2314
|
// src/index.ts
|
|
2489
2315
|
import { Command } from "commander";
|
|
2490
|
-
import
|
|
2316
|
+
import chalk17 from "chalk";
|
|
2491
2317
|
|
|
2492
2318
|
// src/commands/config.ts
|
|
2493
2319
|
init_store();
|
|
@@ -2743,22 +2569,74 @@ async function workflowInfo(workflowId) {
|
|
|
2743
2569
|
for (const [key, val] of Object.entries(detail.parameters)) {
|
|
2744
2570
|
console.log(` ${chalk5.gray(key)}: ${JSON.stringify(val)}`);
|
|
2745
2571
|
}
|
|
2746
|
-
}
|
|
2747
|
-
console.log();
|
|
2748
|
-
} catch (err) {
|
|
2749
|
-
const msg = err.message;
|
|
2750
|
-
printError(`\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uC870\uD68C \uC2E4\uD328: ${msg}`);
|
|
2751
|
-
process.exit(1);
|
|
2752
|
-
}
|
|
2572
|
+
}
|
|
2573
|
+
console.log();
|
|
2574
|
+
} catch (err) {
|
|
2575
|
+
const msg = err.message;
|
|
2576
|
+
printError(`\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uC870\uD68C \uC2E4\uD328: ${msg}`);
|
|
2577
|
+
process.exit(1);
|
|
2578
|
+
}
|
|
2579
|
+
}
|
|
2580
|
+
|
|
2581
|
+
// src/commands/workflow/run.ts
|
|
2582
|
+
init_store();
|
|
2583
|
+
init_workflow();
|
|
2584
|
+
import chalk7 from "chalk";
|
|
2585
|
+
import { randomUUID } from "crypto";
|
|
2586
|
+
|
|
2587
|
+
// src/utils/sse.ts
|
|
2588
|
+
async function parseSSEStream(stream, onEvent, onDone, onError) {
|
|
2589
|
+
let buffer = "";
|
|
2590
|
+
return new Promise((resolve, reject) => {
|
|
2591
|
+
stream.on("data", (chunk) => {
|
|
2592
|
+
buffer += chunk.toString();
|
|
2593
|
+
const parts = buffer.split("\n\n");
|
|
2594
|
+
buffer = parts.pop() ?? "";
|
|
2595
|
+
for (const part of parts) {
|
|
2596
|
+
const lines = part.split("\n");
|
|
2597
|
+
let data = "";
|
|
2598
|
+
for (const line of lines) {
|
|
2599
|
+
if (line.startsWith("data: ")) {
|
|
2600
|
+
data += line.slice(6);
|
|
2601
|
+
} else if (line.startsWith("data:")) {
|
|
2602
|
+
data += line.slice(5);
|
|
2603
|
+
}
|
|
2604
|
+
}
|
|
2605
|
+
if (!data) continue;
|
|
2606
|
+
try {
|
|
2607
|
+
const event = JSON.parse(data);
|
|
2608
|
+
onEvent(event);
|
|
2609
|
+
} catch {
|
|
2610
|
+
onEvent({ type: "token", content: data });
|
|
2611
|
+
}
|
|
2612
|
+
}
|
|
2613
|
+
});
|
|
2614
|
+
stream.on("end", () => {
|
|
2615
|
+
if (buffer.trim()) {
|
|
2616
|
+
const lines = buffer.split("\n");
|
|
2617
|
+
for (const line of lines) {
|
|
2618
|
+
if (line.startsWith("data: ")) {
|
|
2619
|
+
try {
|
|
2620
|
+
const event = JSON.parse(line.slice(6));
|
|
2621
|
+
onEvent(event);
|
|
2622
|
+
} catch {
|
|
2623
|
+
onEvent({ type: "token", content: line.slice(6) });
|
|
2624
|
+
}
|
|
2625
|
+
}
|
|
2626
|
+
}
|
|
2627
|
+
}
|
|
2628
|
+
onDone?.();
|
|
2629
|
+
resolve();
|
|
2630
|
+
});
|
|
2631
|
+
stream.on("error", (err) => {
|
|
2632
|
+
onError?.(err);
|
|
2633
|
+
reject(err);
|
|
2634
|
+
});
|
|
2635
|
+
});
|
|
2753
2636
|
}
|
|
2754
2637
|
|
|
2755
2638
|
// src/commands/workflow/run.ts
|
|
2756
|
-
init_store();
|
|
2757
|
-
init_workflow();
|
|
2758
|
-
init_sse();
|
|
2759
2639
|
init_format();
|
|
2760
|
-
import chalk7 from "chalk";
|
|
2761
|
-
import { randomUUID } from "crypto";
|
|
2762
2640
|
|
|
2763
2641
|
// src/utils/markdown.ts
|
|
2764
2642
|
import chalk6 from "chalk";
|
|
@@ -2803,8 +2681,8 @@ async function workflowRun(workflowId, input, opts) {
|
|
|
2803
2681
|
}
|
|
2804
2682
|
if (!input) {
|
|
2805
2683
|
if (opts.interactive || !process.stdin.isTTY) {
|
|
2806
|
-
const { createInterface:
|
|
2807
|
-
const rl =
|
|
2684
|
+
const { createInterface: createInterface8 } = await import("readline");
|
|
2685
|
+
const rl = createInterface8({ input: process.stdin, output: process.stdout });
|
|
2808
2686
|
input = await new Promise((resolve) => {
|
|
2809
2687
|
rl.question(chalk7.cyan("\uC785\uB825> "), (answer) => {
|
|
2810
2688
|
rl.close();
|
|
@@ -2957,8 +2835,231 @@ function registerWorkflowCommand(program2) {
|
|
|
2957
2835
|
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) }));
|
|
2958
2836
|
}
|
|
2959
2837
|
|
|
2838
|
+
// src/commands/chat.ts
|
|
2839
|
+
init_store();
|
|
2840
|
+
init_workflow();
|
|
2841
|
+
import chalk9 from "chalk";
|
|
2842
|
+
import { createInterface as createInterface2 } from "readline";
|
|
2843
|
+
import { randomUUID as randomUUID2 } from "crypto";
|
|
2844
|
+
init_format();
|
|
2845
|
+
var CHAT_BANNER = `
|
|
2846
|
+
${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")}
|
|
2847
|
+
${chalk9.cyan("\u2502")} ${chalk9.white.bold("XGEN")} ${chalk9.gray("\u2014 \uC6CC\uD06C\uD50C\uB85C\uC6B0 AI \uD130\uBBF8\uB110")} ${chalk9.cyan("\u2502")}
|
|
2848
|
+
${chalk9.cyan("\u2502")} ${chalk9.gray("/help \uB3C4\uC6C0\uB9D0 /workflows \uC804\uD658 /exit")} ${chalk9.cyan("\u2502")}
|
|
2849
|
+
${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")}`;
|
|
2850
|
+
function printHelp() {
|
|
2851
|
+
console.log(`
|
|
2852
|
+
${chalk9.bold("\uC2AC\uB798\uC2DC \uCEE4\uB9E8\uB4DC")}
|
|
2853
|
+
${chalk9.cyan("/workflows")} \uC6CC\uD06C\uD50C\uB85C\uC6B0 \uBAA9\uB85D \uBCF4\uAE30 & \uC804\uD658
|
|
2854
|
+
${chalk9.cyan("/switch")} \uC6CC\uD06C\uD50C\uB85C\uC6B0 \uBC88\uD638\uB85C \uC804\uD658 (\uC608: /switch 3)
|
|
2855
|
+
${chalk9.cyan("/history")} \uD604\uC7AC \uC138\uC158 \uB300\uD654 \uC774\uB825
|
|
2856
|
+
${chalk9.cyan("/clear")} \uD654\uBA74 \uC9C0\uC6B0\uAE30
|
|
2857
|
+
${chalk9.cyan("/info")} \uD604\uC7AC \uC5F0\uACB0 \uC815\uBCF4
|
|
2858
|
+
${chalk9.cyan("/help")} \uC774 \uB3C4\uC6C0\uB9D0
|
|
2859
|
+
${chalk9.cyan("/exit")} \uC885\uB8CC (Ctrl+C\uB3C4 \uAC00\uB2A5)
|
|
2860
|
+
`);
|
|
2861
|
+
}
|
|
2862
|
+
async function promptLine(rl, promptStr) {
|
|
2863
|
+
return new Promise((resolve) => {
|
|
2864
|
+
rl.question(promptStr, (answer) => resolve(answer));
|
|
2865
|
+
});
|
|
2866
|
+
}
|
|
2867
|
+
async function chat(workflowId) {
|
|
2868
|
+
const auth = requireAuth();
|
|
2869
|
+
const server = getServer();
|
|
2870
|
+
let workflows = [];
|
|
2871
|
+
try {
|
|
2872
|
+
workflows = await listWorkflows();
|
|
2873
|
+
} catch {
|
|
2874
|
+
printError("\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uBAA9\uB85D\uC744 \uBD88\uB7EC\uC62C \uC218 \uC5C6\uC2B5\uB2C8\uB2E4");
|
|
2875
|
+
process.exit(1);
|
|
2876
|
+
}
|
|
2877
|
+
if (workflows.length === 0) {
|
|
2878
|
+
printError("\uC0AC\uC6A9 \uAC00\uB2A5\uD55C \uC6CC\uD06C\uD50C\uB85C\uC6B0\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4");
|
|
2879
|
+
process.exit(1);
|
|
2880
|
+
}
|
|
2881
|
+
let current;
|
|
2882
|
+
if (workflowId) {
|
|
2883
|
+
const found = workflows.find((w) => w.id === workflowId || w.workflow_name === workflowId);
|
|
2884
|
+
current = found ?? { id: workflowId, workflow_name: workflowId };
|
|
2885
|
+
} else {
|
|
2886
|
+
console.log(CHAT_BANNER);
|
|
2887
|
+
console.log(chalk9.gray(` \uC11C\uBC84: ${server} | \uC0AC\uC6A9\uC790: ${auth.username}
|
|
2888
|
+
`));
|
|
2889
|
+
console.log(chalk9.bold(" \uC6CC\uD06C\uD50C\uB85C\uC6B0 \uC120\uD0DD:\n"));
|
|
2890
|
+
workflows.forEach((w, i) => {
|
|
2891
|
+
console.log(` ${chalk9.cyan(String(i + 1).padStart(3))} ${w.workflow_name}`);
|
|
2892
|
+
});
|
|
2893
|
+
console.log();
|
|
2894
|
+
const rl2 = createInterface2({ input: process.stdin, output: process.stdout });
|
|
2895
|
+
const answer = await promptLine(rl2, chalk9.cyan(" \uBC88\uD638> "));
|
|
2896
|
+
rl2.close();
|
|
2897
|
+
const idx = parseInt(answer.trim()) - 1;
|
|
2898
|
+
if (isNaN(idx) || idx < 0 || idx >= workflows.length) {
|
|
2899
|
+
current = workflows[0];
|
|
2900
|
+
} else {
|
|
2901
|
+
current = workflows[idx];
|
|
2902
|
+
}
|
|
2903
|
+
}
|
|
2904
|
+
const sessionId = randomUUID2().slice(0, 8);
|
|
2905
|
+
let turnCount = 0;
|
|
2906
|
+
const history = [];
|
|
2907
|
+
console.log();
|
|
2908
|
+
console.log(chalk9.cyan("\u2500".repeat(42)));
|
|
2909
|
+
console.log(chalk9.white.bold(` ${current.workflow_name}`));
|
|
2910
|
+
console.log(chalk9.cyan("\u2500".repeat(42)));
|
|
2911
|
+
console.log(chalk9.gray(" \uBA54\uC2DC\uC9C0\uB97C \uC785\uB825\uD558\uC138\uC694. /help \uB85C \uB3C4\uC6C0\uB9D0.\n"));
|
|
2912
|
+
const rl = createInterface2({
|
|
2913
|
+
input: process.stdin,
|
|
2914
|
+
output: process.stdout
|
|
2915
|
+
});
|
|
2916
|
+
const getPrompt = () => chalk9.cyan("\u276F ");
|
|
2917
|
+
const processInput = async (line) => {
|
|
2918
|
+
const input = line.trim();
|
|
2919
|
+
if (!input) return;
|
|
2920
|
+
if (input.startsWith("/")) {
|
|
2921
|
+
const [cmd, ...args] = input.slice(1).split(" ");
|
|
2922
|
+
switch (cmd.toLowerCase()) {
|
|
2923
|
+
case "exit":
|
|
2924
|
+
case "quit":
|
|
2925
|
+
case "q":
|
|
2926
|
+
console.log(chalk9.gray("\n \uC885\uB8CC\uD569\uB2C8\uB2E4.\n"));
|
|
2927
|
+
rl.close();
|
|
2928
|
+
process.exit(0);
|
|
2929
|
+
break;
|
|
2930
|
+
case "help":
|
|
2931
|
+
case "h":
|
|
2932
|
+
printHelp();
|
|
2933
|
+
break;
|
|
2934
|
+
case "clear":
|
|
2935
|
+
case "cls":
|
|
2936
|
+
console.clear();
|
|
2937
|
+
console.log(chalk9.white.bold(` ${current.workflow_name}`));
|
|
2938
|
+
console.log(chalk9.cyan("\u2500".repeat(42)));
|
|
2939
|
+
break;
|
|
2940
|
+
case "workflows":
|
|
2941
|
+
case "wf":
|
|
2942
|
+
console.log();
|
|
2943
|
+
workflows.forEach((w, i) => {
|
|
2944
|
+
const marker = w.id === current.id ? chalk9.green("\u25B8") : " ";
|
|
2945
|
+
console.log(` ${marker} ${chalk9.cyan(String(i + 1).padStart(2))} ${w.workflow_name}`);
|
|
2946
|
+
});
|
|
2947
|
+
console.log(chalk9.gray("\n /switch <\uBC88\uD638> \uB85C \uC804\uD658\n"));
|
|
2948
|
+
break;
|
|
2949
|
+
case "switch":
|
|
2950
|
+
case "sw": {
|
|
2951
|
+
const num = parseInt(args[0]);
|
|
2952
|
+
if (isNaN(num) || num < 1 || num > workflows.length) {
|
|
2953
|
+
console.log(chalk9.yellow(` 1~${workflows.length} \uC0AC\uC774 \uBC88\uD638\uB97C \uC785\uB825\uD558\uC138\uC694`));
|
|
2954
|
+
} else {
|
|
2955
|
+
current = workflows[num - 1];
|
|
2956
|
+
turnCount = 0;
|
|
2957
|
+
history.length = 0;
|
|
2958
|
+
console.log(chalk9.green(`
|
|
2959
|
+
\uC804\uD658: ${current.workflow_name}
|
|
2960
|
+
`));
|
|
2961
|
+
}
|
|
2962
|
+
break;
|
|
2963
|
+
}
|
|
2964
|
+
case "history":
|
|
2965
|
+
case "hist":
|
|
2966
|
+
if (history.length === 0) {
|
|
2967
|
+
console.log(chalk9.gray(" \uB300\uD654 \uC774\uB825\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.\n"));
|
|
2968
|
+
} else {
|
|
2969
|
+
console.log();
|
|
2970
|
+
for (const h of history) {
|
|
2971
|
+
const label = h.role === "user" ? chalk9.cyan("\uB098") : chalk9.green("AI");
|
|
2972
|
+
const text = h.content.length > 80 ? h.content.slice(0, 80) + "..." : h.content;
|
|
2973
|
+
console.log(` ${label}: ${text}`);
|
|
2974
|
+
}
|
|
2975
|
+
console.log();
|
|
2976
|
+
}
|
|
2977
|
+
break;
|
|
2978
|
+
case "info":
|
|
2979
|
+
console.log(`
|
|
2980
|
+
${chalk9.gray("\uC11C\uBC84:")} ${server}
|
|
2981
|
+
${chalk9.gray("\uC0AC\uC6A9\uC790:")} ${auth.username}
|
|
2982
|
+
${chalk9.gray("\uC6CC\uD06C\uD50C\uB85C\uC6B0:")} ${current.workflow_name}
|
|
2983
|
+
${chalk9.gray("\uC138\uC158:")} ${sessionId}
|
|
2984
|
+
${chalk9.gray("\uD134:")} ${turnCount}
|
|
2985
|
+
`);
|
|
2986
|
+
break;
|
|
2987
|
+
default:
|
|
2988
|
+
console.log(chalk9.yellow(` \uC54C \uC218 \uC5C6\uB294 \uCEE4\uB9E8\uB4DC: /${cmd}. /help \uCC38\uACE0`));
|
|
2989
|
+
}
|
|
2990
|
+
rl.prompt();
|
|
2991
|
+
return;
|
|
2992
|
+
}
|
|
2993
|
+
turnCount++;
|
|
2994
|
+
const interactionId = `${sessionId}_t${turnCount}`;
|
|
2995
|
+
history.push({ role: "user", content: input });
|
|
2996
|
+
process.stdout.write(chalk9.gray(" thinking..."));
|
|
2997
|
+
try {
|
|
2998
|
+
const stream = await executeWorkflowStream({
|
|
2999
|
+
workflow_id: current.id,
|
|
3000
|
+
workflow_name: current.workflow_name,
|
|
3001
|
+
input_data: input,
|
|
3002
|
+
interaction_id: interactionId
|
|
3003
|
+
});
|
|
3004
|
+
process.stdout.write("\r" + " ".repeat(20) + "\r");
|
|
3005
|
+
let fullResponse = "";
|
|
3006
|
+
let hasOutput = false;
|
|
3007
|
+
await parseSSEStream(
|
|
3008
|
+
stream,
|
|
3009
|
+
(event) => {
|
|
3010
|
+
if ((event.type === "token" || !event.type) && event.content) {
|
|
3011
|
+
if (!hasOutput) {
|
|
3012
|
+
hasOutput = true;
|
|
3013
|
+
console.log();
|
|
3014
|
+
}
|
|
3015
|
+
process.stdout.write(event.content);
|
|
3016
|
+
fullResponse += event.content;
|
|
3017
|
+
} else if (event.type === "error") {
|
|
3018
|
+
process.stdout.write("\r" + " ".repeat(20) + "\r");
|
|
3019
|
+
printError(event.error ?? event.content ?? "\uC624\uB958");
|
|
3020
|
+
}
|
|
3021
|
+
},
|
|
3022
|
+
() => {
|
|
3023
|
+
if (hasOutput) {
|
|
3024
|
+
console.log();
|
|
3025
|
+
console.log();
|
|
3026
|
+
}
|
|
3027
|
+
if (fullResponse) {
|
|
3028
|
+
history.push({ role: "assistant", content: fullResponse });
|
|
3029
|
+
}
|
|
3030
|
+
},
|
|
3031
|
+
(err) => {
|
|
3032
|
+
process.stdout.write("\r" + " ".repeat(20) + "\r");
|
|
3033
|
+
printError(`\uC2A4\uD2B8\uB9AC\uBC0D \uC624\uB958: ${err.message}`);
|
|
3034
|
+
}
|
|
3035
|
+
);
|
|
3036
|
+
} catch (err) {
|
|
3037
|
+
process.stdout.write("\r" + " ".repeat(20) + "\r");
|
|
3038
|
+
const msg = err?.response?.data?.detail ?? err.message;
|
|
3039
|
+
printError(`\uC2E4\uD589 \uC2E4\uD328: ${msg}`);
|
|
3040
|
+
}
|
|
3041
|
+
rl.prompt();
|
|
3042
|
+
};
|
|
3043
|
+
rl.setPrompt(getPrompt());
|
|
3044
|
+
rl.prompt();
|
|
3045
|
+
rl.on("line", (line) => {
|
|
3046
|
+
processInput(line).then(() => {
|
|
3047
|
+
});
|
|
3048
|
+
});
|
|
3049
|
+
rl.on("close", () => {
|
|
3050
|
+
console.log(chalk9.gray("\n \uC885\uB8CC\uD569\uB2C8\uB2E4.\n"));
|
|
3051
|
+
process.exit(0);
|
|
3052
|
+
});
|
|
3053
|
+
process.on("SIGINT", () => {
|
|
3054
|
+
console.log(chalk9.gray("\n \uC885\uB8CC\uD569\uB2C8\uB2E4.\n"));
|
|
3055
|
+
process.exit(0);
|
|
3056
|
+
});
|
|
3057
|
+
}
|
|
3058
|
+
function registerChatCommand(program2) {
|
|
3059
|
+
program2.command("chat [workflow-id]").description("\uC778\uD130\uB799\uD2F0\uBE0C \uB300\uD654 \uBAA8\uB4DC").action((workflowId) => chat(workflowId));
|
|
3060
|
+
}
|
|
3061
|
+
|
|
2960
3062
|
// src/index.ts
|
|
2961
|
-
init_chat();
|
|
2962
3063
|
init_provider();
|
|
2963
3064
|
init_agent();
|
|
2964
3065
|
|
|
@@ -2966,7 +3067,7 @@ init_agent();
|
|
|
2966
3067
|
init_store();
|
|
2967
3068
|
init_document();
|
|
2968
3069
|
init_format();
|
|
2969
|
-
import
|
|
3070
|
+
import chalk13 from "chalk";
|
|
2970
3071
|
function registerDocCommand(program2) {
|
|
2971
3072
|
const doc = program2.command("doc").description("\uBB38\uC11C \uAD00\uB9AC");
|
|
2972
3073
|
doc.command("list").alias("ls").description("\uBB38\uC11C \uBAA9\uB85D \uC870\uD68C").option("-c, --collection <id>", "\uCEEC\uB809\uC158 ID").action(async (opts) => {
|
|
@@ -2974,7 +3075,7 @@ function registerDocCommand(program2) {
|
|
|
2974
3075
|
try {
|
|
2975
3076
|
const docs = await listDocuments(opts.collection);
|
|
2976
3077
|
if (!docs.length) {
|
|
2977
|
-
console.log(
|
|
3078
|
+
console.log(chalk13.yellow("\n\uBB38\uC11C\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.\n"));
|
|
2978
3079
|
return;
|
|
2979
3080
|
}
|
|
2980
3081
|
printHeader(`\uBB38\uC11C \uBAA9\uB85D (${docs.length}\uAC1C)`);
|
|
@@ -2998,10 +3099,10 @@ function registerDocCommand(program2) {
|
|
|
2998
3099
|
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) => {
|
|
2999
3100
|
requireAuth();
|
|
3000
3101
|
try {
|
|
3001
|
-
console.log(
|
|
3102
|
+
console.log(chalk13.gray(`\uC5C5\uB85C\uB4DC \uC911: ${file}`));
|
|
3002
3103
|
const result = await uploadDocument(file, opts.collection, opts.name);
|
|
3003
|
-
console.log(
|
|
3004
|
-
console.log(
|
|
3104
|
+
console.log(chalk13.green("\u2713 \uC5C5\uB85C\uB4DC \uC644\uB8CC"));
|
|
3105
|
+
console.log(chalk13.gray(JSON.stringify(result, null, 2)));
|
|
3005
3106
|
} catch (err) {
|
|
3006
3107
|
printError(`\uC5C5\uB85C\uB4DC \uC2E4\uD328: ${err.message}`);
|
|
3007
3108
|
}
|
|
@@ -3011,7 +3112,7 @@ function registerDocCommand(program2) {
|
|
|
3011
3112
|
try {
|
|
3012
3113
|
const d = await getDocumentInfo(id);
|
|
3013
3114
|
printHeader("\uBB38\uC11C \uC815\uBCF4");
|
|
3014
|
-
console.log(
|
|
3115
|
+
console.log(chalk13.gray(JSON.stringify(d, null, 2)));
|
|
3015
3116
|
} catch (err) {
|
|
3016
3117
|
printError(`\uC870\uD68C \uC2E4\uD328: ${err.message}`);
|
|
3017
3118
|
}
|
|
@@ -3022,7 +3123,7 @@ function registerDocCommand(program2) {
|
|
|
3022
3123
|
init_store();
|
|
3023
3124
|
init_ontology();
|
|
3024
3125
|
init_format();
|
|
3025
|
-
import
|
|
3126
|
+
import chalk14 from "chalk";
|
|
3026
3127
|
import { createInterface as createInterface6 } from "readline";
|
|
3027
3128
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
3028
3129
|
function registerOntologyCommand(program2) {
|
|
@@ -3030,19 +3131,19 @@ function registerOntologyCommand(program2) {
|
|
|
3030
3131
|
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) => {
|
|
3031
3132
|
requireAuth();
|
|
3032
3133
|
try {
|
|
3033
|
-
console.log(
|
|
3134
|
+
console.log(chalk14.gray("\n\uC9C8\uC758 \uC911...\n"));
|
|
3034
3135
|
const result = await queryGraphRAG(question, opts.graph, { scs: opts.scs });
|
|
3035
3136
|
if (result.answer) {
|
|
3036
|
-
console.log(
|
|
3137
|
+
console.log(chalk14.bold("\uB2F5\uBCC0:"));
|
|
3037
3138
|
console.log(result.answer);
|
|
3038
3139
|
}
|
|
3039
3140
|
if (result.sources?.length) {
|
|
3040
|
-
console.log(
|
|
3041
|
-
result.sources.forEach((s) => console.log(
|
|
3141
|
+
console.log(chalk14.bold("\n\uCD9C\uCC98:"));
|
|
3142
|
+
result.sources.forEach((s) => console.log(chalk14.gray(` - ${s}`)));
|
|
3042
3143
|
}
|
|
3043
3144
|
if (result.triples_used?.length) {
|
|
3044
|
-
console.log(
|
|
3045
|
-
result.triples_used.forEach((t) => console.log(
|
|
3145
|
+
console.log(chalk14.bold("\n\uC0AC\uC6A9\uB41C \uD2B8\uB9AC\uD50C:"));
|
|
3146
|
+
result.triples_used.forEach((t) => console.log(chalk14.dim(` ${t}`)));
|
|
3046
3147
|
}
|
|
3047
3148
|
console.log();
|
|
3048
3149
|
} catch (err) {
|
|
@@ -3053,9 +3154,9 @@ function registerOntologyCommand(program2) {
|
|
|
3053
3154
|
requireAuth();
|
|
3054
3155
|
const sessionId = randomUUID3();
|
|
3055
3156
|
printHeader("Ontology Chat");
|
|
3056
|
-
console.log(
|
|
3157
|
+
console.log(chalk14.gray("\uBA40\uD2F0\uD134 GraphRAG \uB300\uD654. exit\uB85C \uC885\uB8CC.\n"));
|
|
3057
3158
|
const rl = createInterface6({ input: process.stdin, output: process.stdout });
|
|
3058
|
-
const ask2 = () => new Promise((resolve) => rl.question(
|
|
3159
|
+
const ask2 = () => new Promise((resolve) => rl.question(chalk14.green("\u276F "), (a) => resolve(a.trim())));
|
|
3059
3160
|
while (true) {
|
|
3060
3161
|
const input = await ask2();
|
|
3061
3162
|
if (!input) continue;
|
|
@@ -3069,7 +3170,7 @@ function registerOntologyCommand(program2) {
|
|
|
3069
3170
|
${result.answer}
|
|
3070
3171
|
`);
|
|
3071
3172
|
} catch (err) {
|
|
3072
|
-
console.log(
|
|
3173
|
+
console.log(chalk14.red(`\uC624\uB958: ${err.message}
|
|
3073
3174
|
`));
|
|
3074
3175
|
}
|
|
3075
3176
|
}
|
|
@@ -3079,7 +3180,7 @@ ${result.answer}
|
|
|
3079
3180
|
try {
|
|
3080
3181
|
const stats = await getGraphStats(graphId);
|
|
3081
3182
|
printHeader("\uADF8\uB798\uD504 \uD1B5\uACC4");
|
|
3082
|
-
console.log(
|
|
3183
|
+
console.log(chalk14.gray(JSON.stringify(stats, null, 2)));
|
|
3083
3184
|
console.log();
|
|
3084
3185
|
} catch (err) {
|
|
3085
3186
|
printError(`\uD1B5\uACC4 \uC870\uD68C \uC2E4\uD328: ${err.message}`);
|
|
@@ -3088,44 +3189,43 @@ ${result.answer}
|
|
|
3088
3189
|
}
|
|
3089
3190
|
|
|
3090
3191
|
// src/index.ts
|
|
3091
|
-
init_home();
|
|
3092
3192
|
var VERSION = "0.3.0";
|
|
3093
|
-
var LOGO =
|
|
3193
|
+
var LOGO = chalk17.cyan(`
|
|
3094
3194
|
\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588 \u2588\u2588
|
|
3095
3195
|
\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588 \u2588\u2588
|
|
3096
3196
|
\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588
|
|
3097
3197
|
\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588
|
|
3098
3198
|
\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588
|
|
3099
|
-
`) +
|
|
3199
|
+
`) + chalk17.white.bold(`
|
|
3100
3200
|
\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588 \u2588\u2588
|
|
3101
3201
|
\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588 \u2588\u2588
|
|
3102
3202
|
\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588
|
|
3103
3203
|
\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588
|
|
3104
3204
|
\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588
|
|
3105
|
-
`) +
|
|
3205
|
+
`) + chalk17.gray(` v${VERSION}
|
|
3106
3206
|
`);
|
|
3107
3207
|
var BANNER = LOGO;
|
|
3108
3208
|
var program = new Command();
|
|
3109
3209
|
program.name("xgen").description("OPEN XGEN \u2014 AI Coding Agent + XGEN Platform CLI").version(VERSION).addHelpText("before", BANNER).addHelpText(
|
|
3110
3210
|
"after",
|
|
3111
3211
|
`
|
|
3112
|
-
${
|
|
3113
|
-
${
|
|
3114
|
-
${
|
|
3115
|
-
${
|
|
3116
|
-
${
|
|
3212
|
+
${chalk17.bold("\uC2DC\uC791\uD558\uAE30:")}
|
|
3213
|
+
${chalk17.cyan("xgen provider add")} AI \uD504\uB85C\uBC14\uC774\uB354 \uC124\uC815
|
|
3214
|
+
${chalk17.cyan("xgen agent")} AI \uCF54\uB529 \uC5D0\uC774\uC804\uD2B8
|
|
3215
|
+
${chalk17.cyan("xgen config set-server")} <url> XGEN \uC11C\uBC84 \uC5F0\uACB0
|
|
3216
|
+
${chalk17.cyan("xgen login")} \uC11C\uBC84 \uB85C\uADF8\uC778
|
|
3117
3217
|
|
|
3118
|
-
${
|
|
3119
|
-
${
|
|
3120
|
-
${
|
|
3121
|
-
${
|
|
3218
|
+
${chalk17.bold("AI \uC5D0\uC774\uC804\uD2B8:")}
|
|
3219
|
+
${chalk17.cyan("xgen agent")} \uCF54\uB529 \uC5D0\uC774\uC804\uD2B8 (\uD30C\uC77C, \uD130\uBBF8\uB110, \uAC80\uC0C9)
|
|
3220
|
+
${chalk17.cyan("xgen provider ls")} \uD504\uB85C\uBC14\uC774\uB354 \uBAA9\uB85D
|
|
3221
|
+
${chalk17.cyan("xgen provider add")} \uD504\uB85C\uBC14\uC774\uB354 \uCD94\uAC00
|
|
3122
3222
|
|
|
3123
|
-
${
|
|
3124
|
-
${
|
|
3125
|
-
${
|
|
3126
|
-
${
|
|
3127
|
-
${
|
|
3128
|
-
${
|
|
3223
|
+
${chalk17.bold("XGEN \uD50C\uB7AB\uD3FC:")}
|
|
3224
|
+
${chalk17.cyan("xgen chat")} \uC6CC\uD06C\uD50C\uB85C\uC6B0 \uB300\uD654
|
|
3225
|
+
${chalk17.cyan("xgen wf ls")} \uC6CC\uD06C\uD50C\uB85C\uC6B0 \uBAA9\uB85D
|
|
3226
|
+
${chalk17.cyan("xgen wf run")} <id> "\uC9C8\uBB38" \uC6CC\uD06C\uD50C\uB85C\uC6B0 \uC2E4\uD589
|
|
3227
|
+
${chalk17.cyan("xgen doc ls")} \uBB38\uC11C \uBAA9\uB85D
|
|
3228
|
+
${chalk17.cyan("xgen ont query")} "\uC9C8\uBB38" \uC628\uD1A8\uB85C\uC9C0 \uC9C8\uC758
|
|
3129
3229
|
`
|
|
3130
3230
|
);
|
|
3131
3231
|
registerConfigCommand(program);
|
|
@@ -3137,10 +3237,19 @@ registerAgentCommand(program);
|
|
|
3137
3237
|
registerDocCommand(program);
|
|
3138
3238
|
registerOntologyCommand(program);
|
|
3139
3239
|
if (process.argv.length <= 2) {
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3240
|
+
if (process.stdin.isTTY) {
|
|
3241
|
+
Promise.resolve().then(() => (init_dashboard(), dashboard_exports)).then(
|
|
3242
|
+
({ dashboard: dashboard2 }) => dashboard2().catch((err) => {
|
|
3243
|
+
console.error(chalk17.red(`\uC624\uB958: ${err.message}`));
|
|
3244
|
+
process.exit(1);
|
|
3245
|
+
})
|
|
3246
|
+
);
|
|
3247
|
+
} else {
|
|
3248
|
+
agentRepl().catch((err) => {
|
|
3249
|
+
console.error(chalk17.red(`\uC624\uB958: ${err.message}`));
|
|
3250
|
+
process.exit(1);
|
|
3251
|
+
});
|
|
3252
|
+
}
|
|
3144
3253
|
} else {
|
|
3145
3254
|
program.parse();
|
|
3146
3255
|
}
|