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 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/commands/home.ts
1789
- var home_exports = {};
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
- const activeEnv = getActiveEnvironment();
1799
- const envs = getEnvironments();
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
- console.log();
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 homeMenu() {
1812
- console.log(welcome());
1813
- console.log(chalk12.gray(" v0.4.1\n"));
1814
- showStatus();
1815
- while (true) {
1816
- const provider = getDefaultProvider();
1817
- const server = getServer();
1818
- const auth = getAuth();
1819
- const hasServer = !!(server && auth);
1820
- const items = [];
1821
- items.push({
1822
- key: "a",
1823
- label: chalk12.bold("AI \uC5D0\uC774\uC804\uD2B8"),
1824
- hint: provider ? `${provider.model} \xB7 \uB300\uD654 \uC2DC\uC791` : "\uD504\uB85C\uBC14\uC774\uB354 \uC124\uC815 \uD6C4 \uC2DC\uC791",
1825
- action: async () => {
1826
- await agentRepl();
1827
- console.log();
1828
- showStatus();
1829
- }
1830
- });
1831
- if (hasServer) {
1832
- items.push({
1833
- key: "c",
1834
- label: chalk12.bold("\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uCC44\uD305"),
1835
- hint: `${auth.username}@${server.replace("https://", "")}`,
1836
- action: async () => {
1837
- await chat();
1838
- console.log();
1839
- showStatus();
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
- items.push({
1843
- key: "w",
1844
- label: "\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uAD00\uB9AC",
1845
- hint: "\uBAA9\uB85D \uC870\uD68C \u2192 \uC120\uD0DD \u2192 \uC2E4\uD589/\uC815\uBCF4",
1846
- action: async () => {
1847
- const { getWorkflowListDetail: getWorkflowListDetail2 } = await Promise.resolve().then(() => (init_workflow(), workflow_exports));
1848
- const wfs = await getWorkflowListDetail2();
1849
- if (!wfs.length) {
1850
- console.log(chalk12.yellow("\n \uC6CC\uD06C\uD50C\uB85C\uC6B0\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.\n"));
1851
- return;
1852
- }
1853
- console.log(chalk12.bold(`
1854
- \uC6CC\uD06C\uD50C\uB85C\uC6B0 (${wfs.length}\uAC1C)
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
- items.push({
1907
- key: "d",
1908
- label: "\uBB38\uC11C \uAD00\uB9AC",
1909
- hint: "\uBB38\uC11C \uBAA9\uB85D \uC870\uD68C",
1910
- action: async () => {
1911
- try {
1912
- const { listDocuments: listDocuments2 } = await Promise.resolve().then(() => (init_document(), document_exports));
1913
- const docs = await listDocuments2();
1914
- if (!docs.length) {
1915
- console.log(chalk12.yellow("\n \uBB38\uC11C\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.\n"));
1916
- return;
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
- items.push({
1932
- key: "o",
1933
- label: "\uC628\uD1A8\uB85C\uC9C0 \uC9C8\uC758",
1934
- hint: "GraphRAG \uC6D0\uC0F7 \uC9C8\uC758",
1935
- action: async () => {
1936
- const question = await ask(chalk12.white("\n \uC9C8\uBB38: "));
1937
- if (!question) return;
1938
- try {
1939
- console.log(chalk12.gray(" \uC9C8\uC758 \uC911...\n"));
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
- items.push({
1958
- key: "h",
1959
- label: "\uC2E4\uD589 \uC774\uB825",
1960
- hint: "\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uC2E4\uD589 \uC774\uB825",
1961
- action: async () => {
1962
- try {
1963
- const { getIOLogs: getIOLogs2 } = await Promise.resolve().then(() => (init_workflow(), workflow_exports));
1964
- const logs = await getIOLogs2(void 0, 10);
1965
- if (!logs.length) {
1966
- console.log(chalk12.yellow("\n \uC2E4\uD589 \uC774\uB825\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.\n"));
1967
- return;
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
- const opts = ["\uC0C8\uB85C \uCD94\uAC00"];
2120
- if (providers.length > 1) opts.push("\uAE30\uBCF8 \uBCC0\uACBD");
2121
- if (providers.length > 0) opts.push("\uC0AD\uC81C");
2122
- opts.push("\uB3CC\uC544\uAC00\uAE30");
2123
- opts.forEach((o, i) => console.log(` ${chalk12.cyan(`${i + 1}.`)} ${o}`));
2124
- console.log();
2125
- const c = await ask(chalk12.cyan(" \u276F "));
2126
- const ci = parseInt(c);
2127
- if (ci === 1) {
2128
- await guidedProviderSetup();
2129
- } else if (opts[ci - 1] === "\uAE30\uBCF8 \uBCC0\uACBD") {
2130
- console.log();
2131
- providers.forEach((p, i) => console.log(` ${chalk12.cyan(`${i + 1}.`)} ${p.name} (${p.model})`));
2132
- console.log();
2133
- const pi = parseInt(await ask(chalk12.cyan(" \u276F "))) - 1;
2134
- if (pi >= 0 && pi < providers.length) {
2135
- const { setDefaultProvider: setDefaultProvider2 } = await Promise.resolve().then(() => (init_store(), store_exports));
2136
- setDefaultProvider2(providers[pi].id);
2137
- console.log(chalk12.green(` \u2713 \uAE30\uBCF8: ${providers[pi].name}
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
- async function environmentMenu() {
2154
- const envs = getEnvironments();
2155
- const active = getActiveEnvironment();
2156
- console.log();
2157
- console.log(box(["\uD658\uACBD \uAD00\uB9AC \u2014 XGEN \uC11C\uBC84 \uD504\uB85C\uD544"]));
2158
- console.log();
2159
- if (envs.length > 0) {
2160
- for (const e of envs) {
2161
- const mark = e.id === active?.id ? chalk12.green("\u25CF ") : chalk12.gray(" ");
2162
- console.log(` ${mark}${chalk12.bold(e.name)} ${chalk12.gray(e.url)}`);
2163
- if (e.description) console.log(` ${chalk12.gray(e.description)}`);
2164
- }
2165
- console.log();
2166
- } else {
2167
- console.log(chalk12.gray(" \uB4F1\uB85D\uB41C \uD658\uACBD \uC5C6\uC74C\n"));
2168
- }
2169
- const opts = ["\uC0C8 \uD658\uACBD \uCD94\uAC00", "\uAE30\uBCF8 \uD504\uB9AC\uC14B \uB4F1\uB85D (\uBCF8\uC0AC/\uC81C\uC8FC/\uB86F\uB370\uBAB0)"];
2170
- if (envs.length > 0) opts.push("\uD658\uACBD \uC804\uD658 + \uB85C\uADF8\uC778");
2171
- if (envs.length > 0) opts.push("\uC0AD\uC81C");
2172
- opts.push("\uB3CC\uC544\uAC00\uAE30");
2173
- opts.forEach((o, i) => console.log(` ${chalk12.cyan(`${i + 1}.`)} ${o}`));
2174
- console.log();
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 { apiLogin: apiLogin2 } = await Promise.resolve().then(() => (init_auth(), auth_exports));
2229
- const { setAuth: setAuth2 } = await Promise.resolve().then(() => (init_store(), store_exports));
2230
- const result = await apiLogin2(envs[ei].email, pw);
2231
- if (result.success && result.access_token) {
2232
- setAuth2({ accessToken: result.access_token, refreshToken: result.refresh_token ?? "", userId: result.user_id ?? "", username: result.username ?? "", isAdmin: false, expiresAt: null });
2233
- console.log(chalk12.green(` \u2713 \uB85C\uADF8\uC778: ${result.username}
2234
- `));
2235
- } else {
2236
- console.log(chalk12.red(` \u2717 ${result.message}
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.log(chalk12.red(` \u2717 ${err.message}
2241
- `));
1660
+ console.error(`MCP [${name}] \uC2DC\uC791 \uC2E4\uD328:`, err.message);
2242
1661
  }
2243
1662
  }
2244
1663
  }
2245
- console.log();
2246
- }
2247
- } else if (opts[ci - 1] === "\uC0AD\uC81C") {
2248
- console.log();
2249
- envs.forEach((e, i) => console.log(` ${chalk12.cyan(`${i + 1}.`)} ${e.name}`));
2250
- console.log();
2251
- const di = parseInt(await ask(chalk12.white(" \uC0AD\uC81C \uBC88\uD638: "))) - 1;
2252
- if (di >= 0 && di < envs.length) {
2253
- removeEnvironment(envs[di].id);
2254
- console.log(chalk12.green(` \u2713 \uC0AD\uC81C: ${envs[di].name}
2255
- `));
2256
- }
2257
- }
2258
- }
2259
- var init_home = __esm({
2260
- "src/commands/home.ts"() {
2261
- "use strict";
2262
- init_store();
2263
- init_ui();
2264
- init_agent();
2265
- init_chat();
2266
- init_provider();
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 chalk13 from "chalk";
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 builtinTools = getAllToolDefs();
2283
- const allTools = [...builtinTools];
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: SYSTEM_PROMPT }];
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(chalk13.cyan.bold(" \u276F "), (a) => resolve(a.trim())));
1766
+ const askUser = () => new Promise((resolve) => rl.question(chalk12.cyan(" \u276F "), (a) => resolve(a.trim())));
2312
1767
  process.on("SIGINT", () => {
2313
- console.log(chalk13.gray("\n\uC885\uB8CC\uD569\uB2C8\uB2E4."));
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 === "/exit") {
2322
- console.log(chalk13.gray("\uC885\uB8CC\uD569\uB2C8\uB2E4."));
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
- console.log(chalk13.bold(" \uC2AC\uB798\uC2DC \uCEE4\uB9E8\uB4DC"));
2330
- console.log(chalk13.gray(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
2331
- console.log(` ${chalk13.cyan("/tools")} \uC0AC\uC6A9 \uAC00\uB2A5\uD55C \uB3C4\uAD6C \uBAA9\uB85D`);
2332
- console.log(` ${chalk13.cyan("/provider")} \uD604\uC7AC \uD504\uB85C\uBC14\uC774\uB354 \uC815\uBCF4`);
2333
- console.log(` ${chalk13.cyan("/model")} \uB4F1\uB85D\uB41C \uD504\uB85C\uBC14\uC774\uB354 \uBAA9\uB85D`);
2334
- console.log(` ${chalk13.cyan("/mcp")} MCP \uC11C\uBC84 \uC0C1\uD0DC`);
2335
- console.log(` ${chalk13.cyan("/clear")} \uB300\uD654 \uCD08\uAE30\uD654`);
2336
- console.log(` ${chalk13.cyan("/home")} \uD648 \uBA54\uB274\uB85C \uB3CC\uC544\uAC00\uAE30`);
2337
- console.log(` ${chalk13.cyan("/exit")} \uC885\uB8CC`);
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 = 1;
2343
- console.log(chalk13.gray(" \uB300\uD654 \uCD08\uAE30\uD654\uB428.\n"));
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 === "/tools") {
2347
- console.log(chalk13.bold("\n\uB0B4\uC7A5 \uB3C4\uAD6C:"), getToolNames().join(", "));
2348
- if (mcpManager && mcpManager.serverCount > 0) {
2349
- console.log(chalk13.bold("MCP \uB3C4\uAD6C:"), mcpManager.getAllTools().map((t) => t.function.name).join(", "));
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 === "/provider") {
2355
- console.log(chalk13.gray(`\uD604\uC7AC: ${provider.name} (${provider.model})`));
2356
- console.log(chalk13.gray(`\uBCC0\uACBD: xgen provider add / xgen provider use <id>
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 === "/model") {
2361
- const { getProviders: gp } = await Promise.resolve().then(() => (init_store(), store_exports));
2362
- const all = gp();
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 === "/home" || input === "/menu") {
2374
- console.log(chalk13.gray("\uC5D0\uC774\uC804\uD2B8\uB97C \uC885\uB8CC\uD558\uACE0 \uD648\uC73C\uB85C \uB3CC\uC544\uAC11\uB2C8\uB2E4."));
2375
- mcpManager?.stopAll();
2376
- rl.close();
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 === "/mcp") {
2382
- if (mcpManager && mcpManager.serverCount > 0) {
2383
- console.log(chalk13.bold("\nMCP \uC11C\uBC84:"), mcpManager.getServerNames().join(", "));
2384
- console.log(chalk13.gray("\uB3C4\uAD6C:"), mcpManager.getAllTools().map((t) => t.function.name).join(", "));
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 runAgentLoop(client2, provider.model, messages, allTools);
1844
+ await runLoop(client2, provider.model, messages, allTools);
2394
1845
  } catch (err) {
2395
- console.log(chalk13.red(`
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 runAgentLoop(client2, model, messages, tools2) {
2402
- const MAX_ITERATIONS = 20;
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(chalk13.green("\n AI \u203A") + " ");
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
- console.log(chalk13.gray(` \u2699 `) + chalk13.white.bold(tc.name) + chalk13.gray(` ${summarizeArgs(args)}`));
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 (mcpManager?.isMcpTool(tc.name)) {
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...(truncated)" : toolResult;
2445
- messages.push({
2446
- role: "tool",
2447
- tool_call_id: tc.id,
2448
- content: truncated
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 summarizeArgs(args) {
2455
- const parts = [];
2456
- for (const [k, v] of Object.entries(args)) {
2457
- const s = String(v);
2458
- parts.push(`${k}: ${s.length > 40 ? s.slice(0, 40) + "..." : s}`);
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 \uCF54\uB529 \uC5D0\uC774\uC804\uD2B8").action(async () => {
1970
+ program2.command("agent").description("OPEN XGEN AI \uC5D0\uC774\uC804\uD2B8").action(async () => {
2464
1971
  await agentRepl();
2465
1972
  });
2466
1973
  }
2467
- var SYSTEM_PROMPT, mcpManager;
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 chalk16 from "chalk";
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: createInterface7 } = await import("readline");
2807
- const rl = createInterface7({ input: process.stdin, output: process.stdout });
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 chalk14 from "chalk";
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(chalk14.yellow("\n\uBB38\uC11C\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.\n"));
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(chalk14.gray(`\uC5C5\uB85C\uB4DC \uC911: ${file}`));
3102
+ console.log(chalk13.gray(`\uC5C5\uB85C\uB4DC \uC911: ${file}`));
3002
3103
  const result = await uploadDocument(file, opts.collection, opts.name);
3003
- console.log(chalk14.green("\u2713 \uC5C5\uB85C\uB4DC \uC644\uB8CC"));
3004
- console.log(chalk14.gray(JSON.stringify(result, null, 2)));
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(chalk14.gray(JSON.stringify(d, null, 2)));
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 chalk15 from "chalk";
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(chalk15.gray("\n\uC9C8\uC758 \uC911...\n"));
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(chalk15.bold("\uB2F5\uBCC0:"));
3137
+ console.log(chalk14.bold("\uB2F5\uBCC0:"));
3037
3138
  console.log(result.answer);
3038
3139
  }
3039
3140
  if (result.sources?.length) {
3040
- console.log(chalk15.bold("\n\uCD9C\uCC98:"));
3041
- result.sources.forEach((s) => console.log(chalk15.gray(` - ${s}`)));
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(chalk15.bold("\n\uC0AC\uC6A9\uB41C \uD2B8\uB9AC\uD50C:"));
3045
- result.triples_used.forEach((t) => console.log(chalk15.dim(` ${t}`)));
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(chalk15.gray("\uBA40\uD2F0\uD134 GraphRAG \uB300\uD654. exit\uB85C \uC885\uB8CC.\n"));
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(chalk15.green("\u276F "), (a) => resolve(a.trim())));
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(chalk15.red(`\uC624\uB958: ${err.message}
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(chalk15.gray(JSON.stringify(stats, null, 2)));
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 = chalk16.cyan(`
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
- `) + chalk16.white.bold(`
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
- `) + chalk16.gray(` v${VERSION}
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
- ${chalk16.bold("\uC2DC\uC791\uD558\uAE30:")}
3113
- ${chalk16.cyan("xgen provider add")} AI \uD504\uB85C\uBC14\uC774\uB354 \uC124\uC815
3114
- ${chalk16.cyan("xgen agent")} AI \uCF54\uB529 \uC5D0\uC774\uC804\uD2B8
3115
- ${chalk16.cyan("xgen config set-server")} <url> XGEN \uC11C\uBC84 \uC5F0\uACB0
3116
- ${chalk16.cyan("xgen login")} \uC11C\uBC84 \uB85C\uADF8\uC778
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
- ${chalk16.bold("AI \uC5D0\uC774\uC804\uD2B8:")}
3119
- ${chalk16.cyan("xgen agent")} \uCF54\uB529 \uC5D0\uC774\uC804\uD2B8 (\uD30C\uC77C, \uD130\uBBF8\uB110, \uAC80\uC0C9)
3120
- ${chalk16.cyan("xgen provider ls")} \uD504\uB85C\uBC14\uC774\uB354 \uBAA9\uB85D
3121
- ${chalk16.cyan("xgen provider add")} \uD504\uB85C\uBC14\uC774\uB354 \uCD94\uAC00
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
- ${chalk16.bold("XGEN \uD50C\uB7AB\uD3FC:")}
3124
- ${chalk16.cyan("xgen chat")} \uC6CC\uD06C\uD50C\uB85C\uC6B0 \uB300\uD654
3125
- ${chalk16.cyan("xgen wf ls")} \uC6CC\uD06C\uD50C\uB85C\uC6B0 \uBAA9\uB85D
3126
- ${chalk16.cyan("xgen wf run")} <id> "\uC9C8\uBB38" \uC6CC\uD06C\uD50C\uB85C\uC6B0 \uC2E4\uD589
3127
- ${chalk16.cyan("xgen doc ls")} \uBB38\uC11C \uBAA9\uB85D
3128
- ${chalk16.cyan("xgen ont query")} "\uC9C8\uBB38" \uC628\uD1A8\uB85C\uC9C0 \uC9C8\uC758
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
- homeMenu().catch((err) => {
3141
- console.error(chalk16.red(`\uC624\uB958: ${err.message}`));
3142
- process.exit(1);
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
  }