openxgen 0.4.1 → 0.5.1

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
@@ -318,6 +318,16 @@ var init_auth = __esm({
318
318
  });
319
319
 
320
320
  // src/api/workflow.ts
321
+ var workflow_exports = {};
322
+ __export(workflow_exports, {
323
+ executeWorkflow: () => executeWorkflow,
324
+ executeWorkflowStream: () => executeWorkflowStream,
325
+ getExecutionStatus: () => getExecutionStatus,
326
+ getIOLogs: () => getIOLogs,
327
+ getWorkflowDetail: () => getWorkflowDetail,
328
+ getWorkflowListDetail: () => getWorkflowListDetail,
329
+ listWorkflows: () => listWorkflows
330
+ });
321
331
  async function listWorkflows(userId) {
322
332
  const client2 = getClient();
323
333
  const params = {};
@@ -333,7 +343,7 @@ async function getWorkflowDetail(workflowId) {
333
343
  async function getWorkflowListDetail() {
334
344
  const client2 = getClient();
335
345
  const res = await client2.get("/api/workflow/list/detail");
336
- return res.data;
346
+ return res.data.workflows ?? res.data;
337
347
  }
338
348
  async function executeWorkflowStream(request) {
339
349
  const client2 = getClient();
@@ -345,6 +355,16 @@ async function executeWorkflowStream(request) {
345
355
  });
346
356
  return res.data;
347
357
  }
358
+ async function executeWorkflow(request) {
359
+ const client2 = getClient();
360
+ const res = await client2.post("/api/workflow/execute/based_id", request);
361
+ return res.data;
362
+ }
363
+ async function getExecutionStatus(executionId) {
364
+ const client2 = getClient();
365
+ const res = await client2.get(`/api/workflow/execute/status/${executionId}`);
366
+ return res.data;
367
+ }
348
368
  async function getIOLogs(workflowId, limit = 20) {
349
369
  const client2 = getClient();
350
370
  const params = { limit };
@@ -359,66 +379,6 @@ var init_workflow = __esm({
359
379
  }
360
380
  });
361
381
 
362
- // src/commands/workflow/list.ts
363
- var list_exports = {};
364
- __export(list_exports, {
365
- workflowList: () => workflowList
366
- });
367
- import chalk4 from "chalk";
368
- async function workflowList(opts) {
369
- requireAuth();
370
- try {
371
- if (opts.detail) {
372
- const workflows = await getWorkflowListDetail();
373
- if (!workflows || workflows.length === 0) {
374
- console.log(chalk4.yellow("\n\uC6CC\uD06C\uD50C\uB85C\uC6B0\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.\n"));
375
- return;
376
- }
377
- printHeader(`\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uBAA9\uB85D (${workflows.length}\uAC1C)`);
378
- console.log();
379
- printTable(
380
- ["#", "ID", "\uC774\uB984", "\uBC30\uD3EC", "\uC5C5\uB370\uC774\uD2B8"],
381
- workflows.map((w, i) => [
382
- String(i + 1),
383
- (w.workflow_id ?? w.id ?? "-").slice(0, 12),
384
- truncate(w.workflow_name ?? "-", 30),
385
- w.deploy_status === "deployed" ? chalk4.green("\uBC30\uD3EC\uB428") : chalk4.gray("\uBBF8\uBC30\uD3EC"),
386
- formatDate(w.updated_at)
387
- ])
388
- );
389
- } else {
390
- const workflows = await listWorkflows();
391
- if (!workflows || workflows.length === 0) {
392
- console.log(chalk4.yellow("\n\uC6CC\uD06C\uD50C\uB85C\uC6B0\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.\n"));
393
- return;
394
- }
395
- printHeader(`\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uBAA9\uB85D (${workflows.length}\uAC1C)`);
396
- console.log();
397
- printTable(
398
- ["#", "ID", "\uC774\uB984"],
399
- workflows.map((w, i) => [
400
- String(i + 1),
401
- (w.workflow_id ?? w.id ?? "-").slice(0, 12),
402
- w.workflow_name ?? "-"
403
- ])
404
- );
405
- }
406
- console.log();
407
- } catch (err) {
408
- const msg = err.message;
409
- printError(`\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uBAA9\uB85D \uC870\uD68C \uC2E4\uD328: ${msg}`);
410
- process.exit(1);
411
- }
412
- }
413
- var init_list = __esm({
414
- "src/commands/workflow/list.ts"() {
415
- "use strict";
416
- init_store();
417
- init_workflow();
418
- init_format();
419
- }
420
- });
421
-
422
382
  // src/utils/sse.ts
423
383
  async function parseSSEStream(stream, onEvent, onDone, onError) {
424
384
  let buffer = "";
@@ -475,6 +435,178 @@ var init_sse = __esm({
475
435
  }
476
436
  });
477
437
 
438
+ // src/utils/markdown.ts
439
+ import chalk6 from "chalk";
440
+ function renderMarkdown(text) {
441
+ let result = text;
442
+ result = result.replace(CODE_BLOCK_RE, (_match, lang, code) => {
443
+ const trimmed = code.trimEnd();
444
+ const header = lang ? chalk6.gray(` \u2500\u2500 ${lang} \u2500\u2500`) : chalk6.gray(" \u2500\u2500 code \u2500\u2500");
445
+ const lines = trimmed.split("\n").map((l) => chalk6.white(` ${l}`)).join("\n");
446
+ return `
447
+ ${header}
448
+ ${lines}
449
+ ${chalk6.gray(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500")}
450
+ `;
451
+ });
452
+ result = result.replace(INLINE_CODE_RE, (_m, code) => chalk6.cyan(`\`${code}\``));
453
+ result = result.replace(BOLD_RE, (_m, text2) => chalk6.bold(text2));
454
+ result = result.replace(HEADING_RE, (_m, hashes, text2) => {
455
+ if (hashes.length === 1) return chalk6.bold.underline(text2);
456
+ if (hashes.length === 2) return chalk6.bold(text2);
457
+ return chalk6.bold.dim(text2);
458
+ });
459
+ result = result.replace(LIST_RE, (_m, indent, text2) => `${indent}${chalk6.cyan("\u2022")} ${text2}`);
460
+ result = result.replace(LINK_RE, (_m, label, url) => `${chalk6.blue.underline(label)} ${chalk6.gray(`(${url})`)}`);
461
+ return result;
462
+ }
463
+ var CODE_BLOCK_RE, INLINE_CODE_RE, BOLD_RE, HEADING_RE, LIST_RE, LINK_RE;
464
+ var init_markdown = __esm({
465
+ "src/utils/markdown.ts"() {
466
+ "use strict";
467
+ CODE_BLOCK_RE = /```(\w*)\n([\s\S]*?)```/g;
468
+ INLINE_CODE_RE = /`([^`]+)`/g;
469
+ BOLD_RE = /\*\*(.+?)\*\*/g;
470
+ HEADING_RE = /^(#{1,3})\s+(.+)$/gm;
471
+ LIST_RE = /^(\s*)[-*]\s+(.+)$/gm;
472
+ LINK_RE = /\[([^\]]+)\]\(([^)]+)\)/g;
473
+ }
474
+ });
475
+
476
+ // src/commands/workflow/run.ts
477
+ var run_exports = {};
478
+ __export(run_exports, {
479
+ workflowRun: () => workflowRun
480
+ });
481
+ import chalk7 from "chalk";
482
+ import { randomUUID } from "crypto";
483
+ async function workflowRun(workflowId, input, opts) {
484
+ const auth = requireAuth();
485
+ let workflowName = workflowId;
486
+ try {
487
+ const detail = await getWorkflowDetail(workflowId);
488
+ workflowName = detail.workflow_name ?? workflowId;
489
+ } catch {
490
+ }
491
+ if (!input) {
492
+ if (opts.interactive || !process.stdin.isTTY) {
493
+ const { createInterface: createInterface7 } = await import("readline");
494
+ const rl = createInterface7({ input: process.stdin, output: process.stdout });
495
+ input = await new Promise((resolve) => {
496
+ rl.question(chalk7.cyan("\uC785\uB825> "), (answer) => {
497
+ rl.close();
498
+ resolve(answer.trim());
499
+ });
500
+ });
501
+ } else {
502
+ printError("\uC785\uB825\uAC12\uC774 \uD544\uC694\uD569\uB2C8\uB2E4. \uC0AC\uC6A9\uBC95:");
503
+ console.log(' xgen workflow run <id> "\uC785\uB825 \uD14D\uC2A4\uFFFD\uFFFD\uFFFD"');
504
+ console.log(" xgen workflow run -i <id>");
505
+ process.exit(1);
506
+ }
507
+ }
508
+ if (!input) {
509
+ printError("\uC785\uB825\uAC12\uC774 \uBE44\uC5B4\uC788\uC2B5\uB2C8\uB2E4");
510
+ process.exit(1);
511
+ }
512
+ const interactionId = `cli_${randomUUID().slice(0, 8)}`;
513
+ printHeader(`\uC2E4\uD589: ${workflowName}`);
514
+ printInfo(`\uC785\uB825: ${input}`);
515
+ console.log();
516
+ try {
517
+ const stream = await executeWorkflowStream({
518
+ workflow_id: workflowId,
519
+ workflow_name: workflowName,
520
+ input_data: input,
521
+ interaction_id: interactionId
522
+ });
523
+ let hasOutput = false;
524
+ let fullResponse = "";
525
+ await parseSSEStream(
526
+ stream,
527
+ (event) => {
528
+ switch (event.type) {
529
+ case "token":
530
+ if (event.content) {
531
+ if (!hasOutput) {
532
+ hasOutput = true;
533
+ console.log();
534
+ }
535
+ process.stdout.write(event.content);
536
+ fullResponse += event.content;
537
+ }
538
+ break;
539
+ case "log":
540
+ if (opts.logs && event.content) {
541
+ process.stderr.write(chalk7.gray(`[LOG] ${event.content}
542
+ `));
543
+ }
544
+ break;
545
+ case "node_status":
546
+ if (opts.logs) {
547
+ const nodeName = event.node_name ?? event.node_id ?? "?";
548
+ const status = event.status ?? "?";
549
+ process.stderr.write(
550
+ chalk7.gray(`[\uB178\uB4DC] ${nodeName}: ${status}
551
+ `)
552
+ );
553
+ }
554
+ break;
555
+ case "tool":
556
+ if (opts.logs) {
557
+ process.stderr.write(chalk7.gray(`[\uB3C4\uAD6C] ${JSON.stringify(event.data)}
558
+ `));
559
+ }
560
+ break;
561
+ case "complete":
562
+ break;
563
+ case "error":
564
+ console.log();
565
+ printError(event.error ?? event.content ?? "\uC54C \uC218 \uC5C6\uB294 \uC624\uB958");
566
+ break;
567
+ default:
568
+ if (event.content) {
569
+ if (!hasOutput) {
570
+ process.stdout.write(chalk7.green("\uC751\uB2F5: "));
571
+ hasOutput = true;
572
+ }
573
+ process.stdout.write(event.content);
574
+ }
575
+ }
576
+ },
577
+ () => {
578
+ if (hasOutput) {
579
+ console.log();
580
+ if (fullResponse.includes("```") || fullResponse.includes("**")) {
581
+ console.log(chalk7.gray("\u2500".repeat(40)));
582
+ console.log(renderMarkdown(fullResponse));
583
+ }
584
+ }
585
+ console.log();
586
+ console.log(chalk7.gray(`\uC138\uC158: ${interactionId}`));
587
+ },
588
+ (err) => {
589
+ console.log();
590
+ printError(`\uC2A4\uD2B8\uB9AC\uBC0D \uC624\uB958: ${err.message}`);
591
+ }
592
+ );
593
+ } catch (err) {
594
+ const msg = err?.response?.data?.detail ?? err.message;
595
+ printError(`\uC2E4\uD589 \uC2E4\uD328: ${msg}`);
596
+ process.exit(1);
597
+ }
598
+ }
599
+ var init_run = __esm({
600
+ "src/commands/workflow/run.ts"() {
601
+ "use strict";
602
+ init_store();
603
+ init_workflow();
604
+ init_sse();
605
+ init_format();
606
+ init_markdown();
607
+ }
608
+ });
609
+
478
610
  // src/commands/chat.ts
479
611
  import chalk9 from "chalk";
480
612
  import { createInterface as createInterface2 } from "readline";
@@ -706,11 +838,34 @@ ${chalk9.cyan("\u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u250
706
838
  }
707
839
  });
708
840
 
709
- // src/commands/provider.ts
841
+ // src/utils/ui.ts
710
842
  import chalk10 from "chalk";
711
843
  import { createInterface as createInterface3 } from "readline";
712
- import OpenAI from "openai";
713
- function prompt2(question) {
844
+ function box(lines, color = "cyan") {
845
+ const c = chalk10[color];
846
+ const inner = W - 4;
847
+ const top = c(" \u256D" + "\u2500".repeat(inner) + "\u256E");
848
+ const bot = c(" \u2570" + "\u2500".repeat(inner) + "\u256F");
849
+ const body = lines.map((line) => {
850
+ const clean = line.replace(/\x1b\[[0-9;]*m/g, "");
851
+ const pad = Math.max(0, inner - clean.length);
852
+ return c(" \u2502 ") + line + " ".repeat(pad) + c(" \u2502");
853
+ });
854
+ return [top, ...body, bot].join("\n");
855
+ }
856
+ function divider(label) {
857
+ if (label) {
858
+ const rest = W - label.length - 6;
859
+ return chalk10.gray(` \u2500\u2500 ${label} ${"\u2500".repeat(Math.max(0, rest))}`);
860
+ }
861
+ return chalk10.gray(" " + "\u2500".repeat(W - 2));
862
+ }
863
+ function statusDot(active, label, detail) {
864
+ const dot = active ? chalk10.green("\u25CF") : chalk10.gray("\u25CB");
865
+ const d = detail ? chalk10.gray(` ${detail}`) : "";
866
+ return ` ${dot} ${label}${d}`;
867
+ }
868
+ function ask(question) {
714
869
  return new Promise((resolve) => {
715
870
  const rl = createInterface3({ input: process.stdin, output: process.stdout });
716
871
  rl.question(question, (answer) => {
@@ -719,77 +874,115 @@ function prompt2(question) {
719
874
  });
720
875
  });
721
876
  }
722
- async function guidedProviderSetup() {
723
- console.log(chalk10.cyan.bold("\n \u26A1 OPEN XGEN \u2014 \uD504\uB85C\uBC14\uC774\uB354 \uC124\uC815\n"));
724
- console.log(chalk10.gray(" AI \uC5D0\uC774\uC804\uD2B8\uB97C \uC0AC\uC6A9\uD558\uB824\uBA74 \uD504\uB85C\uBC14\uC774\uB354\uB97C \uC124\uC815\uD558\uC138\uC694.\n"));
725
- console.log(chalk10.bold(" \uD504\uB85C\uBC14\uC774\uB354 \uC120\uD0DD:\n"));
726
- PRESETS.forEach((p, i) => {
727
- console.log(` ${chalk10.cyan(`${i + 1})`)} ${p.label} ${chalk10.gray(`\u2014 ${p.defaultModel}`)}`);
728
- });
729
- console.log();
730
- const choice = await prompt2(chalk10.white(" \uBC88\uD638 \uC120\uD0DD: "));
731
- const idx = parseInt(choice) - 1;
732
- if (isNaN(idx) || idx < 0 || idx >= PRESETS.length) {
733
- printError("\uC798\uBABB\uB41C \uC120\uD0DD\uC785\uB2C8\uB2E4.");
734
- return null;
735
- }
736
- const preset = PRESETS[idx];
737
- console.log(chalk10.green(`
738
- \u2713 ${preset.label} \uC120\uD0DD\uB428
739
- `));
740
- let apiKey = "";
741
- if (preset.needsKey) {
742
- console.log(chalk10.gray(` ${preset.keyHint}
743
- `));
744
- apiKey = await prompt2(chalk10.white(" API Key: "));
745
- if (!apiKey) {
746
- printError("API Key\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4.");
747
- return null;
877
+ function welcome() {
878
+ const logo = chalk10.cyan(`
879
+ \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588 \u2588\u2588
880
+ \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588 \u2588\u2588
881
+ \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588
882
+ \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588
883
+ \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588`) + chalk10.white.bold(`
884
+ \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588 \u2588\u2588
885
+ \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588 \u2588\u2588
886
+ \u2588\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588
887
+ \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588
888
+ \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588`);
889
+ return logo;
890
+ }
891
+ var W;
892
+ var init_ui = __esm({
893
+ "src/utils/ui.ts"() {
894
+ "use strict";
895
+ W = Math.min(process.stdout.columns || 60, 70);
896
+ }
897
+ });
898
+
899
+ // src/commands/provider.ts
900
+ import chalk11 from "chalk";
901
+ import OpenAI from "openai";
902
+ function detectEnvKey(preset) {
903
+ if (!preset.envKey) return null;
904
+ return process.env[preset.envKey] ?? null;
905
+ }
906
+ async function guidedProviderSetup() {
907
+ console.log();
908
+ console.log(box(["OPEN XGEN \u2014 \uD504\uB85C\uBC14\uC774\uB354 \uC124\uC815", "", chalk11.gray("AI \uC5D0\uC774\uC804\uD2B8\uC5D0 \uC0AC\uC6A9\uD560 LLM\uC744 \uC120\uD0DD\uD558\uC138\uC694.")]));
909
+ console.log();
910
+ console.log(chalk11.bold(" \uD504\uB85C\uBC14\uC774\uB354 \uC120\uD0DD:\n"));
911
+ PRESETS.forEach((p, i) => {
912
+ const envDetected = detectEnvKey(p);
913
+ const envTag = envDetected ? chalk11.green(" [\uD0A4 \uAC10\uC9C0\uB428]") : "";
914
+ const free = !p.needsKey ? chalk11.green(" [\uBB34\uB8CC]") : "";
915
+ console.log(` ${chalk11.cyan(`${String(i + 1).padStart(2)}.`)} ${p.label}${free}${envTag}`);
916
+ console.log(` ${chalk11.gray(p.defaultModel)}`);
917
+ });
918
+ console.log();
919
+ const choice = await ask(chalk11.cyan(" \uBC88\uD638: "));
920
+ const idx = parseInt(choice) - 1;
921
+ if (isNaN(idx) || idx < 0 || idx >= PRESETS.length) {
922
+ console.log(chalk11.red(" \uC798\uBABB\uB41C \uC120\uD0DD.\n"));
923
+ return null;
924
+ }
925
+ const preset = PRESETS[idx];
926
+ console.log(chalk11.green(`
927
+ \u2713 ${preset.label}
928
+ `));
929
+ let apiKey = "";
930
+ if (preset.needsKey) {
931
+ const envKey = detectEnvKey(preset);
932
+ if (envKey) {
933
+ console.log(chalk11.green(` API Key \uC790\uB3D9 \uAC10\uC9C0 (${preset.envKey})`));
934
+ const useEnv = await ask(chalk11.white(` \uC774 \uD0A4\uB97C \uC0AC\uC6A9\uD560\uAE4C\uC694? (Y/n): `));
935
+ if (useEnv.toLowerCase() !== "n") {
936
+ apiKey = envKey;
937
+ }
938
+ }
939
+ if (!apiKey) {
940
+ console.log(chalk11.gray(` \uBC1C\uAE09: ${preset.keyHint}
941
+ `));
942
+ apiKey = await ask(chalk11.white(" API Key: "));
943
+ if (!apiKey) {
944
+ console.log(chalk11.red(" API Key \uD544\uC694.\n"));
945
+ return null;
946
+ }
748
947
  }
749
948
  }
750
949
  let baseUrl = preset.baseUrl;
751
- if (preset.type === "custom") {
752
- const url = await prompt2(chalk10.white(" Base URL: "));
753
- if (!url) {
754
- printError("Base URL\uC774 \uD544\uC694\uD569\uB2C8\uB2E4.");
950
+ if (preset.label === "\uAE30\uD0C0 (OpenAI \uD638\uD658 \uC11C\uBC84)") {
951
+ baseUrl = await ask(chalk11.white(" Base URL: "));
952
+ if (!baseUrl) {
953
+ console.log(chalk11.red(" URL \uD544\uC694.\n"));
755
954
  return null;
756
955
  }
757
- baseUrl = url;
758
- } else if (preset.type === "ollama") {
759
- const url = await prompt2(chalk10.white(` Base URL [${preset.baseUrl}]: `));
760
- if (url) baseUrl = url;
761
956
  }
762
957
  let model = preset.defaultModel;
763
958
  if (preset.models.length > 0) {
764
- console.log(chalk10.bold("\n \uBAA8\uB378 \uC120\uD0DD:\n"));
959
+ console.log(chalk11.bold("\n \uBAA8\uB378:\n"));
960
+ const defaultIdx = preset.models.indexOf(preset.defaultModel);
765
961
  preset.models.forEach((m, i) => {
766
- const isDefault = m === preset.defaultModel ? chalk10.gray(" (\uAE30\uBCF8)") : "";
767
- console.log(` ${chalk10.cyan(`${i + 1})`)} ${m}${isDefault}`);
962
+ const tag = i === defaultIdx ? chalk11.green(" \u2190 \uCD94\uCC9C") : "";
963
+ console.log(` ${chalk11.cyan(`${String(i + 1).padStart(2)}.`)} ${m}${tag}`);
768
964
  });
769
- console.log(` ${chalk10.cyan(`${preset.models.length + 1})`)} \uC9C1\uC811 \uC785\uB825`);
965
+ console.log(` ${chalk11.cyan(`${String(preset.models.length + 1).padStart(2)}.`)} \uC9C1\uC811 \uC785\uB825`);
770
966
  console.log();
771
- const defaultIdx = preset.models.indexOf(preset.defaultModel);
772
- const mc = await prompt2(chalk10.white(` \uBC88\uD638 \uC120\uD0DD [${defaultIdx + 1}]: `));
773
- if (!mc) {
967
+ const mc = await ask(chalk11.cyan(` \uBC88\uD638 [${defaultIdx + 1}]: `));
968
+ if (!mc || mc === String(defaultIdx + 1)) {
774
969
  model = preset.defaultModel;
775
970
  } else {
776
971
  const mi = parseInt(mc) - 1;
777
- if (!isNaN(mi) && mi >= 0 && mi < preset.models.length) {
972
+ if (mi >= 0 && mi < preset.models.length) {
778
973
  model = preset.models[mi];
779
974
  } else if (parseInt(mc) === preset.models.length + 1) {
780
- model = await prompt2(chalk10.white(" \uBAA8\uB378 \uC774\uB984: ")) || preset.defaultModel;
781
- } else {
782
- model = preset.defaultModel;
975
+ model = await ask(chalk11.white(" \uBAA8\uB378\uBA85: ")) || preset.defaultModel;
783
976
  }
784
977
  }
785
- } else {
786
- model = await prompt2(chalk10.white(` \uBAA8\uB378 \uC774\uB984 [${preset.defaultModel}]: `)) || preset.defaultModel;
978
+ } else if (preset.label === "\uAE30\uD0C0 (OpenAI \uD638\uD658 \uC11C\uBC84)") {
979
+ model = await ask(chalk11.white(` \uBAA8\uB378\uBA85 [${preset.defaultModel}]: `)) || preset.defaultModel;
787
980
  }
788
- console.log(chalk10.green(`
789
- \u2713 \uBAA8\uB378: ${model}`));
790
- console.log(chalk10.gray("\n \uC5F0\uACB0 \uD14C\uC2A4\uD2B8 \uC911..."));
981
+ console.log(chalk11.green(`
982
+ \u2713 ${preset.label} \xB7 ${model}`));
983
+ console.log(chalk11.gray(" \uC5F0\uACB0 \uD14C\uC2A4\uD2B8 \uC911...\n"));
791
984
  const provider = {
792
- id: preset.type,
985
+ id: preset.label.toLowerCase().replace(/[^a-z0-9]/g, "-").replace(/-+/g, "-"),
793
986
  name: preset.label,
794
987
  type: preset.type,
795
988
  baseUrl,
@@ -797,50 +990,41 @@ async function guidedProviderSetup() {
797
990
  model
798
991
  };
799
992
  try {
800
- const client2 = new OpenAI({
801
- apiKey: apiKey || "ollama",
802
- baseURL: baseUrl
803
- });
804
- const res = await client2.chat.completions.create({
993
+ const client2 = new OpenAI({ apiKey: apiKey || "ollama", baseURL: baseUrl });
994
+ await client2.chat.completions.create({
805
995
  model,
806
996
  messages: [{ role: "user", content: "Hi" }],
807
997
  max_tokens: 5
808
998
  });
809
- if (res.choices[0]) {
810
- console.log(chalk10.green(" \u2713 \uC5F0\uACB0 \uC131\uACF5!\n"));
811
- }
999
+ console.log(chalk11.green(" \u2713 \uC5F0\uACB0 \uC131\uACF5!\n"));
812
1000
  } catch (err) {
813
- console.log(chalk10.yellow(` \u26A0 \uC5F0\uACB0 \uD14C\uC2A4\uD2B8 \uC2E4\uD328: ${err.message}`));
814
- console.log(chalk10.gray(" \uC124\uC815\uC740 \uC800\uC7A5\uB429\uB2C8\uB2E4. \uB098\uC911\uC5D0 \uB2E4\uC2DC \uC2DC\uB3C4\uD558\uC138\uC694.\n"));
1001
+ console.log(chalk11.yellow(` \u26A0 \uD14C\uC2A4\uD2B8 \uC2E4\uD328: ${err.message}`));
1002
+ console.log(chalk11.gray(" \uC124\uC815\uC740 \uC800\uC7A5\uB429\uB2C8\uB2E4.\n"));
815
1003
  }
816
1004
  addProvider(provider);
817
- console.log(chalk10.green.bold(` \u2713 ${preset.label} (${model}) \uC124\uC815 \uC644\uB8CC!
818
- `));
819
- console.log(chalk10.gray(` \uC774\uC81C ${chalk10.cyan("xgen agent")} \uB610\uB294 ${chalk10.cyan("xgen")} \uC73C\uB85C \uC2DC\uC791\uD558\uC138\uC694.
1005
+ console.log(chalk11.green.bold(` \u2713 \uC124\uC815 \uC644\uB8CC! ${preset.label} (${model})
820
1006
  `));
821
1007
  return provider;
822
1008
  }
823
1009
  function registerProviderCommand(program2) {
824
1010
  const prov = program2.command("provider").description("AI \uD504\uB85C\uBC14\uC774\uB354 \uAD00\uB9AC");
825
- prov.command("add").description("\uD504\uB85C\uBC14\uC774\uB354 \uCD94\uAC00 (\uAC00\uC774\uB4DC \uC124\uC815)").action(async () => {
1011
+ prov.command("add").description("\uD504\uB85C\uBC14\uC774\uB354 \uCD94\uAC00").action(async () => {
826
1012
  await guidedProviderSetup();
827
1013
  });
828
1014
  prov.command("list").alias("ls").description("\uD504\uB85C\uBC14\uC774\uB354 \uBAA9\uB85D").action(() => {
829
1015
  const providers = getProviders();
830
1016
  const defaultP = getDefaultProvider();
831
1017
  if (providers.length === 0) {
832
- console.log(chalk10.yellow("\n \uD504\uB85C\uBC14\uC774\uB354\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4."));
833
- console.log(` ${chalk10.cyan("xgen provider add")} \uB85C \uCD94\uAC00\uD558\uC138\uC694.
834
- `);
1018
+ console.log(chalk11.yellow("\n \uD504\uB85C\uBC14\uC774\uB354 \uC5C6\uC74C. xgen provider add\n"));
835
1019
  return;
836
1020
  }
837
- console.log(chalk10.cyan.bold(`
1021
+ console.log(chalk11.cyan.bold(`
838
1022
  \uD504\uB85C\uBC14\uC774\uB354 (${providers.length}\uAC1C)
839
1023
  `));
840
1024
  printTable(
841
1025
  ["", "ID", "\uC774\uB984", "\uD0C0\uC785", "\uBAA8\uB378"],
842
1026
  providers.map((p) => [
843
- p.id === defaultP?.id ? chalk10.green("\u25CF") : " ",
1027
+ p.id === defaultP?.id ? chalk11.green("\u25CF") : " ",
844
1028
  p.id,
845
1029
  p.name,
846
1030
  p.type,
@@ -850,18 +1034,10 @@ function registerProviderCommand(program2) {
850
1034
  console.log();
851
1035
  });
852
1036
  prov.command("remove <id>").description("\uD504\uB85C\uBC14\uC774\uB354 \uC81C\uAC70").action((id) => {
853
- if (removeProvider(id)) {
854
- printSuccess(`\uD504\uB85C\uBC14\uC774\uB354 \uC81C\uAC70: ${id}`);
855
- } else {
856
- printError(`\uD504\uB85C\uBC14\uC774\uB354\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${id}`);
857
- }
1037
+ removeProvider(id) ? printSuccess(`\uC81C\uAC70: ${id}`) : printError(`\uC5C6\uC74C: ${id}`);
858
1038
  });
859
1039
  prov.command("use <id>").description("\uAE30\uBCF8 \uD504\uB85C\uBC14\uC774\uB354 \uC124\uC815").action((id) => {
860
- if (setDefaultProvider(id)) {
861
- printSuccess(`\uAE30\uBCF8 \uD504\uB85C\uBC14\uC774\uB354: ${id}`);
862
- } else {
863
- printError(`\uD504\uB85C\uBC14\uC774\uB354\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${id}`);
864
- }
1040
+ setDefaultProvider(id) ? printSuccess(`\uAE30\uBCF8: ${id}`) : printError(`\uC5C6\uC74C: ${id}`);
865
1041
  });
866
1042
  }
867
1043
  var PRESETS;
@@ -870,44 +1046,143 @@ var init_provider = __esm({
870
1046
  "use strict";
871
1047
  init_store();
872
1048
  init_format();
1049
+ init_ui();
873
1050
  PRESETS = [
874
1051
  {
875
1052
  label: "OpenAI",
876
1053
  type: "openai",
877
1054
  defaultModel: "gpt-4o-mini",
878
- models: ["gpt-4o", "gpt-4o-mini", "gpt-4.1", "gpt-4.1-mini", "o3-mini"],
1055
+ models: [
1056
+ "gpt-4o",
1057
+ "gpt-4o-mini",
1058
+ "gpt-4.1",
1059
+ "gpt-4.1-mini",
1060
+ "gpt-4.1-nano",
1061
+ "o3-mini",
1062
+ "o4-mini",
1063
+ "gpt-3.5-turbo"
1064
+ ],
879
1065
  needsKey: true,
880
- keyHint: "https://platform.openai.com/api-keys \uC5D0\uC11C \uBC1C\uAE09"
1066
+ keyHint: "https://platform.openai.com/api-keys",
1067
+ envKey: "OPENAI_API_KEY"
881
1068
  },
882
1069
  {
883
1070
  label: "Google Gemini",
884
1071
  type: "gemini",
885
1072
  baseUrl: "https://generativelanguage.googleapis.com/v1beta/openai",
886
1073
  defaultModel: "gemini-2.0-flash",
887
- models: ["gemini-2.0-flash", "gemini-2.5-pro-preview-06-05", "gemini-2.5-flash-preview-05-20"],
1074
+ models: [
1075
+ "gemini-2.5-pro-preview-06-05",
1076
+ "gemini-2.5-flash-preview-05-20",
1077
+ "gemini-2.0-flash",
1078
+ "gemini-2.0-flash-lite",
1079
+ "gemini-1.5-pro",
1080
+ "gemini-1.5-flash"
1081
+ ],
888
1082
  needsKey: true,
889
- keyHint: "https://aistudio.google.com/apikey \uC5D0\uC11C \uBC1C\uAE09"
1083
+ keyHint: "https://aistudio.google.com/apikey",
1084
+ envKey: "GEMINI_API_KEY"
890
1085
  },
891
1086
  {
892
- label: "Ollama (\uB85C\uCEEC)",
1087
+ label: "Anthropic (Claude)",
1088
+ type: "anthropic",
1089
+ baseUrl: "https://api.anthropic.com/v1",
1090
+ defaultModel: "claude-sonnet-4-20250514",
1091
+ models: [
1092
+ "claude-opus-4-20250514",
1093
+ "claude-sonnet-4-20250514",
1094
+ "claude-haiku-4-5-20251001",
1095
+ "claude-3.5-sonnet-20241022"
1096
+ ],
1097
+ needsKey: true,
1098
+ keyHint: "https://console.anthropic.com/settings/keys",
1099
+ envKey: "ANTHROPIC_API_KEY"
1100
+ },
1101
+ {
1102
+ label: "Ollama (\uB85C\uCEEC \uBB34\uB8CC)",
893
1103
  type: "ollama",
894
1104
  baseUrl: "http://localhost:11434/v1",
895
1105
  defaultModel: "llama3.1",
896
- models: ["llama3.1", "llama3.2", "codellama", "mistral", "qwen2.5-coder"],
1106
+ models: [
1107
+ "llama3.1",
1108
+ "llama3.2",
1109
+ "llama3.3",
1110
+ "codellama",
1111
+ "deepseek-coder-v2",
1112
+ "qwen2.5-coder",
1113
+ "qwen2.5",
1114
+ "mistral",
1115
+ "mixtral",
1116
+ "phi3",
1117
+ "gemma2"
1118
+ ],
897
1119
  needsKey: false,
898
- keyHint: "https://ollama.ai \uC5D0\uC11C \uC124\uCE58"
1120
+ keyHint: "https://ollama.ai \uC124\uCE58 \uD6C4 ollama pull <\uBAA8\uB378>"
899
1121
  },
900
1122
  {
901
- label: "Anthropic (Claude)",
902
- type: "anthropic",
903
- baseUrl: "https://api.anthropic.com/v1",
904
- defaultModel: "claude-sonnet-4-20250514",
905
- models: ["claude-sonnet-4-20250514", "claude-opus-4-20250514", "claude-haiku-4-5-20251001"],
1123
+ label: "Groq (\uBE60\uB978 \uCD94\uB860)",
1124
+ type: "custom",
1125
+ baseUrl: "https://api.groq.com/openai/v1",
1126
+ defaultModel: "llama-3.3-70b-versatile",
1127
+ models: [
1128
+ "llama-3.3-70b-versatile",
1129
+ "llama-3.1-8b-instant",
1130
+ "mixtral-8x7b-32768",
1131
+ "gemma2-9b-it"
1132
+ ],
1133
+ needsKey: true,
1134
+ keyHint: "https://console.groq.com/keys",
1135
+ envKey: "GROQ_API_KEY"
1136
+ },
1137
+ {
1138
+ label: "Together AI",
1139
+ type: "custom",
1140
+ baseUrl: "https://api.together.xyz/v1",
1141
+ defaultModel: "meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo",
1142
+ models: [
1143
+ "meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo",
1144
+ "meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo",
1145
+ "mistralai/Mixtral-8x7B-Instruct-v0.1",
1146
+ "Qwen/Qwen2.5-72B-Instruct-Turbo"
1147
+ ],
1148
+ needsKey: true,
1149
+ keyHint: "https://api.together.xyz/settings/api-keys",
1150
+ envKey: "TOGETHER_API_KEY"
1151
+ },
1152
+ {
1153
+ label: "OpenRouter (\uBA40\uD2F0 \uBAA8\uB378)",
1154
+ type: "custom",
1155
+ baseUrl: "https://openrouter.ai/api/v1",
1156
+ defaultModel: "openai/gpt-4o-mini",
1157
+ models: [
1158
+ "openai/gpt-4o",
1159
+ "openai/gpt-4o-mini",
1160
+ "anthropic/claude-sonnet-4",
1161
+ "anthropic/claude-haiku-4.5",
1162
+ "google/gemini-2.0-flash-exp",
1163
+ "meta-llama/llama-3.3-70b-instruct",
1164
+ "deepseek/deepseek-chat-v3"
1165
+ ],
1166
+ needsKey: true,
1167
+ keyHint: "https://openrouter.ai/keys",
1168
+ envKey: "OPENROUTER_API_KEY"
1169
+ },
1170
+ {
1171
+ label: "DeepSeek",
1172
+ type: "custom",
1173
+ baseUrl: "https://api.deepseek.com/v1",
1174
+ defaultModel: "deepseek-chat",
1175
+ models: [
1176
+ "deepseek-chat",
1177
+ "deepseek-coder",
1178
+ "deepseek-reasoner"
1179
+ ],
906
1180
  needsKey: true,
907
- keyHint: "https://console.anthropic.com/settings/keys \uC5D0\uC11C \uBC1C\uAE09"
1181
+ keyHint: "https://platform.deepseek.com/api_keys",
1182
+ envKey: "DEEPSEEK_API_KEY"
908
1183
  },
909
1184
  {
910
- label: "Custom (OpenAI \uD638\uD658 \uC11C\uBC84)",
1185
+ label: "\uAE30\uD0C0 (OpenAI \uD638\uD658 \uC11C\uBC84)",
911
1186
  type: "custom",
912
1187
  defaultModel: "gpt-4o-mini",
913
1188
  models: [],
@@ -1547,61 +1822,91 @@ var init_client2 = __esm({
1547
1822
  }
1548
1823
  });
1549
1824
 
1550
- // src/utils/ui.ts
1551
- import chalk11 from "chalk";
1552
- import { createInterface as createInterface5 } from "readline";
1553
- function box(lines, color = "cyan") {
1554
- const c = chalk11[color];
1555
- const inner = W - 4;
1556
- const top = c(" \u256D" + "\u2500".repeat(inner) + "\u256E");
1557
- const bot = c(" \u2570" + "\u2500".repeat(inner) + "\u256F");
1558
- const body = lines.map((line) => {
1559
- const clean = line.replace(/\x1b\[[0-9;]*m/g, "");
1560
- const pad = Math.max(0, inner - clean.length);
1561
- return c(" \u2502 ") + line + " ".repeat(pad) + c(" \u2502");
1825
+ // src/api/document.ts
1826
+ var document_exports = {};
1827
+ __export(document_exports, {
1828
+ getDocumentInfo: () => getDocumentInfo,
1829
+ listDocuments: () => listDocuments,
1830
+ uploadDocument: () => uploadDocument
1831
+ });
1832
+ import { createReadStream, statSync } from "fs";
1833
+ import { basename } from "path";
1834
+ async function listDocuments(collectionId) {
1835
+ const client2 = getClient();
1836
+ const params = {};
1837
+ if (collectionId) params.collection_id = collectionId;
1838
+ const res = await client2.get("/api/documents/list", { params });
1839
+ return res.data.documents ?? res.data ?? [];
1840
+ }
1841
+ async function uploadDocument(filePath, collectionId, name) {
1842
+ const client2 = getClient();
1843
+ const stat = statSync(filePath);
1844
+ const fileName = name || basename(filePath);
1845
+ const FormData = (await import("buffer")).Blob ? globalThis.FormData : null;
1846
+ if (!FormData) throw new Error("FormData not available");
1847
+ const form = new FormData();
1848
+ const fileBlob = new Blob([createReadStream(filePath)]);
1849
+ form.append("file", fileBlob, fileName);
1850
+ if (collectionId) form.append("collection_id", collectionId);
1851
+ const res = await client2.post("/api/documents/upload", form, {
1852
+ headers: { "Content-Type": "multipart/form-data" },
1853
+ maxBodyLength: stat.size + 1024 * 1024
1562
1854
  });
1563
- return [top, ...body, bot].join("\n");
1855
+ return res.data;
1564
1856
  }
1565
- function divider(label) {
1566
- if (label) {
1567
- const rest = W - label.length - 6;
1568
- return chalk11.gray(` \u2500\u2500 ${label} ${"\u2500".repeat(Math.max(0, rest))}`);
1569
- }
1570
- return chalk11.gray(" " + "\u2500".repeat(W - 2));
1857
+ async function getDocumentInfo(docId) {
1858
+ const client2 = getClient();
1859
+ const res = await client2.get(`/api/documents/${docId}`);
1860
+ return res.data;
1571
1861
  }
1572
- function statusDot(active, label, detail) {
1573
- const dot = active ? chalk11.green("\u25CF") : chalk11.gray("\u25CB");
1574
- const d = detail ? chalk11.gray(` ${detail}`) : "";
1575
- return ` ${dot} ${label}${d}`;
1862
+ var init_document = __esm({
1863
+ "src/api/document.ts"() {
1864
+ "use strict";
1865
+ init_client();
1866
+ }
1867
+ });
1868
+
1869
+ // src/api/ontology.ts
1870
+ var ontology_exports = {};
1871
+ __export(ontology_exports, {
1872
+ getGraphStats: () => getGraphStats,
1873
+ listGraphs: () => listGraphs,
1874
+ queryGraphRAG: () => queryGraphRAG,
1875
+ queryGraphRAGMultiTurn: () => queryGraphRAGMultiTurn
1876
+ });
1877
+ async function queryGraphRAG(query, graphId, opts) {
1878
+ const client2 = getClient();
1879
+ const res = await client2.post("/api/graph-rag", {
1880
+ query,
1881
+ graph_id: graphId,
1882
+ use_scs: opts?.scs ?? true
1883
+ });
1884
+ return res.data;
1576
1885
  }
1577
- function ask(question) {
1578
- return new Promise((resolve) => {
1579
- const rl = createInterface5({ input: process.stdin, output: process.stdout });
1580
- rl.question(question, (answer) => {
1581
- rl.close();
1582
- resolve(answer.trim());
1583
- });
1886
+ async function queryGraphRAGMultiTurn(query, sessionId, graphId, opts) {
1887
+ const client2 = getClient();
1888
+ const res = await client2.post("/api/graph-rag/multi-turn", {
1889
+ query,
1890
+ session_id: sessionId,
1891
+ graph_id: graphId,
1892
+ max_turns: opts?.maxTurns ?? 5
1584
1893
  });
1894
+ return res.data;
1585
1895
  }
1586
- function welcome() {
1587
- const logo = chalk11.cyan(`
1588
- \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588 \u2588\u2588
1589
- \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588 \u2588\u2588
1590
- \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588
1591
- \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588
1592
- \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588`) + chalk11.white.bold(`
1593
- \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588 \u2588\u2588
1594
- \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588 \u2588\u2588
1595
- \u2588\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588
1596
- \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588
1597
- \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588`);
1598
- return logo;
1896
+ async function getGraphStats(graphId) {
1897
+ const client2 = getClient();
1898
+ const res = await client2.get(`/api/graph/${graphId}/stats`);
1899
+ return res.data;
1599
1900
  }
1600
- var W;
1601
- var init_ui = __esm({
1602
- "src/utils/ui.ts"() {
1901
+ async function listGraphs() {
1902
+ const client2 = getClient();
1903
+ const res = await client2.get("/api/graph/list");
1904
+ return res.data.graphs ?? res.data ?? [];
1905
+ }
1906
+ var init_ontology = __esm({
1907
+ "src/api/ontology.ts"() {
1603
1908
  "use strict";
1604
- W = Math.min(process.stdout.columns || 60, 70);
1909
+ init_client();
1605
1910
  }
1606
1911
  });
1607
1912
 
@@ -1617,23 +1922,13 @@ function showStatus() {
1617
1922
  const auth = getAuth();
1618
1923
  console.log(divider("\uC0C1\uD0DC"));
1619
1924
  console.log();
1620
- if (provider) {
1621
- console.log(statusDot(true, chalk12.bold("AI \uC5D0\uC774\uC804\uD2B8"), `${provider.name} \xB7 ${provider.model}`));
1622
- } else {
1623
- console.log(statusDot(false, "AI \uC5D0\uC774\uC804\uD2B8", "\uBBF8\uC124\uC815"));
1624
- }
1625
- if (server && auth) {
1626
- console.log(statusDot(true, chalk12.bold("XGEN \uC11C\uBC84"), `${auth.username} \xB7 ${server.replace("https://", "")}`));
1627
- } else if (server) {
1628
- console.log(statusDot(false, "XGEN \uC11C\uBC84", `${server.replace("https://", "")} \xB7 \uB85C\uADF8\uC778 \uD544\uC694`));
1629
- } else {
1630
- console.log(statusDot(false, "XGEN \uC11C\uBC84", "\uBBF8\uC5F0\uACB0"));
1631
- }
1925
+ 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"));
1926
+ 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"));
1632
1927
  console.log();
1633
1928
  }
1634
1929
  async function homeMenu() {
1635
1930
  console.log(welcome());
1636
- console.log(chalk12.gray(" v0.3.2\n"));
1931
+ console.log(chalk12.gray(" v0.4.1\n"));
1637
1932
  showStatus();
1638
1933
  while (true) {
1639
1934
  const provider = getDefaultProvider();
@@ -1642,77 +1937,196 @@ async function homeMenu() {
1642
1937
  const hasServer = !!(server && auth);
1643
1938
  const items = [];
1644
1939
  items.push({
1645
- label: provider ? `${chalk12.bold("AI \uC5D0\uC774\uC804\uD2B8")} ${chalk12.gray(`(${provider.model})`)}` : chalk12.bold("AI \uC5D0\uC774\uC804\uD2B8 \uC2DC\uC791\uD558\uAE30"),
1646
- hint: provider ? "\uB300\uD654 \uC2DC\uC791" : "\uD504\uB85C\uBC14\uC774\uB354 \uC124\uC815 \u2192 \uBC14\uB85C \uC2DC\uC791",
1940
+ key: "a",
1941
+ label: chalk12.bold("AI \uC5D0\uC774\uC804\uD2B8"),
1942
+ hint: provider ? `${provider.model} \xB7 \uB300\uD654 \uC2DC\uC791` : "\uD504\uB85C\uBC14\uC774\uB354 \uC124\uC815 \uD6C4 \uC2DC\uC791",
1647
1943
  action: async () => {
1648
1944
  await agentRepl();
1649
1945
  console.log();
1650
1946
  showStatus();
1651
- return false;
1652
1947
  }
1653
1948
  });
1654
1949
  if (hasServer) {
1655
1950
  items.push({
1951
+ key: "c",
1656
1952
  label: chalk12.bold("\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uCC44\uD305"),
1657
1953
  hint: `${auth.username}@${server.replace("https://", "")}`,
1658
1954
  action: async () => {
1659
1955
  await chat();
1660
1956
  console.log();
1661
1957
  showStatus();
1662
- return false;
1663
1958
  }
1664
1959
  });
1665
1960
  items.push({
1666
- label: "\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uBAA9\uB85D",
1667
- hint: "\uC870\uD68C",
1961
+ key: "w",
1962
+ label: "\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uAD00\uB9AC",
1963
+ hint: "\uBAA9\uB85D \uC870\uD68C \u2192 \uC120\uD0DD \u2192 \uC2E4\uD589/\uC815\uBCF4",
1964
+ action: async () => {
1965
+ const { listWorkflows: listWorkflows2 } = await Promise.resolve().then(() => (init_workflow(), workflow_exports));
1966
+ const wfs = await listWorkflows2();
1967
+ if (!wfs.length) {
1968
+ console.log(chalk12.yellow("\n \uC6CC\uD06C\uD50C\uB85C\uC6B0\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.\n"));
1969
+ return;
1970
+ }
1971
+ console.log(chalk12.bold(`
1972
+ \uC6CC\uD06C\uD50C\uB85C\uC6B0 (${wfs.length}\uAC1C)
1973
+ `));
1974
+ wfs.forEach((w, i) => {
1975
+ const id = (w.workflow_id ?? w.id ?? "").toString();
1976
+ const deployed = w.is_deployed;
1977
+ const tag = deployed ? chalk12.green(" [\uBC30\uD3EC]") : "";
1978
+ console.log(` ${chalk12.cyan(`${String(i + 1).padStart(3)}.`)} ${w.workflow_name}${tag}`);
1979
+ console.log(` ${chalk12.gray(id)}`);
1980
+ });
1981
+ console.log();
1982
+ console.log(chalk12.gray(" \uBC88\uD638 \uC785\uB825 \u2192 \uC2E4\uD589 / Enter \u2192 \uB3CC\uC544\uAC00\uAE30"));
1983
+ const choice2 = await ask(chalk12.cyan("\n \u276F "));
1984
+ if (!choice2) return;
1985
+ const wi = parseInt(choice2) - 1;
1986
+ if (wi < 0 || wi >= wfs.length) return;
1987
+ const selected2 = wfs[wi];
1988
+ const wfId = (selected2.workflow_id ?? selected2.id ?? "").toString();
1989
+ console.log(chalk12.green(`
1990
+ \u2713 ${selected2.workflow_name}
1991
+ `));
1992
+ const input = await ask(chalk12.white(" \uBA54\uC2DC\uC9C0: "));
1993
+ if (!input) return;
1994
+ const { workflowRun: workflowRun2 } = await Promise.resolve().then(() => (init_run(), run_exports));
1995
+ await workflowRun2(wfId, input, { logs: false, interactive: false });
1996
+ }
1997
+ });
1998
+ items.push({
1999
+ key: "d",
2000
+ label: "\uBB38\uC11C \uAD00\uB9AC",
2001
+ hint: "\uBB38\uC11C \uBAA9\uB85D \uC870\uD68C",
2002
+ action: async () => {
2003
+ try {
2004
+ const { listDocuments: listDocuments2 } = await Promise.resolve().then(() => (init_document(), document_exports));
2005
+ const docs = await listDocuments2();
2006
+ if (!docs.length) {
2007
+ console.log(chalk12.yellow("\n \uBB38\uC11C\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.\n"));
2008
+ return;
2009
+ }
2010
+ console.log(chalk12.bold(`
2011
+ \uBB38\uC11C (${docs.length}\uAC1C)
2012
+ `));
2013
+ docs.forEach((d, i) => {
2014
+ console.log(` ${chalk12.cyan(`${i + 1}.`)} ${d.file_name ?? d.name ?? "-"} ${chalk12.gray(d.file_type ?? "")}`);
2015
+ });
2016
+ console.log();
2017
+ } catch (err) {
2018
+ console.log(chalk12.red(` \uC624\uB958: ${err.message}
2019
+ `));
2020
+ }
2021
+ }
2022
+ });
2023
+ items.push({
2024
+ key: "o",
2025
+ label: "\uC628\uD1A8\uB85C\uC9C0 \uC9C8\uC758",
2026
+ hint: "GraphRAG \uC6D0\uC0F7 \uC9C8\uC758",
2027
+ action: async () => {
2028
+ const question = await ask(chalk12.white("\n \uC9C8\uBB38: "));
2029
+ if (!question) return;
2030
+ try {
2031
+ console.log(chalk12.gray(" \uC9C8\uC758 \uC911...\n"));
2032
+ const { queryGraphRAG: queryGraphRAG2 } = await Promise.resolve().then(() => (init_ontology(), ontology_exports));
2033
+ const result = await queryGraphRAG2(question);
2034
+ if (result.answer) {
2035
+ console.log(chalk12.bold(" \uB2F5\uBCC0:"));
2036
+ console.log(` ${result.answer}`);
2037
+ }
2038
+ if (result.sources?.length) {
2039
+ console.log(chalk12.bold("\n \uCD9C\uCC98:"));
2040
+ result.sources.forEach((s) => console.log(chalk12.gray(` - ${s}`)));
2041
+ }
2042
+ console.log();
2043
+ } catch (err) {
2044
+ console.log(chalk12.red(` \uC624\uB958: ${err.message}
2045
+ `));
2046
+ }
2047
+ }
2048
+ });
2049
+ items.push({
2050
+ key: "h",
2051
+ label: "\uC2E4\uD589 \uC774\uB825",
2052
+ hint: "\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uC2E4\uD589 \uC774\uB825",
1668
2053
  action: async () => {
1669
- const { workflowList: workflowList2 } = await Promise.resolve().then(() => (init_list(), list_exports));
1670
- await workflowList2({ detail: false });
1671
- return false;
2054
+ try {
2055
+ const { getIOLogs: getIOLogs2 } = await Promise.resolve().then(() => (init_workflow(), workflow_exports));
2056
+ const logs = await getIOLogs2(void 0, 10);
2057
+ if (!logs.length) {
2058
+ console.log(chalk12.yellow("\n \uC2E4\uD589 \uC774\uB825\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.\n"));
2059
+ return;
2060
+ }
2061
+ console.log(chalk12.bold(`
2062
+ \uCD5C\uADFC \uC2E4\uD589 \uC774\uB825 (${logs.length}\uAC1C)
2063
+ `));
2064
+ logs.forEach((log, i) => {
2065
+ console.log(` ${chalk12.cyan(`${i + 1}.`)} ${chalk12.gray(log.created_at ?? "-")}`);
2066
+ console.log(` \uC785\uB825: ${(log.input_data ?? "").slice(0, 50)}`);
2067
+ console.log(` \uCD9C\uB825: ${chalk12.gray((log.output_data ?? "").slice(0, 50))}`);
2068
+ });
2069
+ console.log();
2070
+ } catch (err) {
2071
+ console.log(chalk12.red(` \uC624\uB958: ${err.message}
2072
+ `));
2073
+ }
1672
2074
  }
1673
2075
  });
1674
2076
  }
1675
2077
  items.push({
1676
- label: hasServer ? "XGEN \uC11C\uBC84 \uC7AC\uC124\uC815" : chalk12.bold("XGEN \uC11C\uBC84 \uC5F0\uACB0"),
1677
- hint: hasServer ? "\uC11C\uBC84 \uBCC0\uACBD / \uC7AC\uB85C\uADF8\uC778" : "\uC11C\uBC84 URL + \uB85C\uADF8\uC778",
2078
+ key: "s",
2079
+ label: hasServer ? "\uC11C\uBC84 \uC7AC\uC124\uC815" : chalk12.bold("XGEN \uC11C\uBC84 \uC5F0\uACB0"),
2080
+ hint: hasServer ? "\uC11C\uBC84 \uBCC0\uACBD / \uC7AC\uB85C\uADF8\uC778" : "URL + \uB85C\uADF8\uC778",
1678
2081
  action: async () => {
1679
2082
  await serverSetup();
1680
2083
  showStatus();
1681
- return false;
1682
2084
  }
1683
2085
  });
1684
2086
  items.push({
2087
+ key: "p",
1685
2088
  label: "\uD504\uB85C\uBC14\uC774\uB354 \uAD00\uB9AC",
1686
- hint: `${getProviders().length}\uAC1C \uB4F1\uB85D\uB428`,
2089
+ hint: `${getProviders().length}\uAC1C \uB4F1\uB85D`,
1687
2090
  action: async () => {
1688
2091
  await providerMenu();
1689
2092
  showStatus();
1690
- return false;
1691
2093
  }
1692
2094
  });
1693
2095
  console.log(divider("\uBA54\uB274"));
1694
- for (let i = 0; i < items.length; i++) {
1695
- const num = chalk12.cyan.bold(` ${String(i + 1).padStart(2)}.`);
1696
- console.log(` ${num} ${items[i].label}`);
1697
- console.log(` ${chalk12.gray(items[i].hint)}`);
2096
+ console.log();
2097
+ if (hasServer) {
2098
+ console.log(chalk12.gray(" AI"));
2099
+ }
2100
+ const aiItem = items.find((i) => i.key === "a");
2101
+ console.log(` ${chalk12.cyan.bold(aiItem.key + ".")} ${aiItem.label} ${chalk12.gray("\u2014 " + aiItem.hint)}`);
2102
+ if (hasServer) {
2103
+ console.log();
2104
+ console.log(chalk12.gray(" XGEN \uD50C\uB7AB\uD3FC"));
2105
+ for (const item of items.filter((i) => ["c", "w", "r", "d", "o", "h"].includes(i.key))) {
2106
+ console.log(` ${chalk12.cyan.bold(item.key + ".")} ${item.label} ${chalk12.gray("\u2014 " + item.hint)}`);
2107
+ }
2108
+ }
2109
+ console.log();
2110
+ console.log(chalk12.gray(" \uC124\uC815"));
2111
+ for (const item of items.filter((i) => ["s", "p"].includes(i.key))) {
2112
+ console.log(` ${chalk12.cyan.bold(item.key + ".")} ${item.label} ${chalk12.gray("\u2014 " + item.hint)}`);
1698
2113
  }
1699
- console.log(` ${chalk12.gray(" q. \uC885\uB8CC")}`);
2114
+ console.log(` ${chalk12.gray("q. \uC885\uB8CC")}`);
1700
2115
  console.log();
1701
2116
  const choice = await ask(chalk12.cyan(" \u276F "));
1702
- if (choice === "q" || choice === "exit" || choice === "") {
1703
- if (choice === "") continue;
1704
- console.log(chalk12.gray("\n \u{1F44B} \uB2E4\uC74C\uC5D0 \uB610.\n"));
2117
+ if (choice === "q" || choice === "exit") {
2118
+ console.log(chalk12.gray("\n \u{1F44B}\n"));
1705
2119
  break;
1706
2120
  }
1707
- const idx = parseInt(choice) - 1;
1708
- if (isNaN(idx) || idx < 0 || idx >= items.length) {
1709
- console.log(chalk12.red(` \uC798\uBABB\uB41C \uC785\uB825\uC785\uB2C8\uB2E4.
2121
+ if (!choice) continue;
2122
+ const selected = items.find((i) => i.key === choice);
2123
+ if (!selected) {
2124
+ console.log(chalk12.red(` "${choice}" \u2014 \uC798\uBABB\uB41C \uC785\uB825
1710
2125
  `));
1711
2126
  continue;
1712
2127
  }
1713
2128
  try {
1714
- const shouldExit = await items[idx].action();
1715
- if (shouldExit) break;
2129
+ await selected.action();
1716
2130
  } catch (err) {
1717
2131
  console.log(chalk12.red(`
1718
2132
  \uC624\uB958: ${err.message}
@@ -1722,7 +2136,7 @@ async function homeMenu() {
1722
2136
  }
1723
2137
  async function serverSetup() {
1724
2138
  console.log();
1725
- console.log(box(["XGEN \uC11C\uBC84 \uC5F0\uACB0"], "cyan"));
2139
+ console.log(box(["XGEN \uC11C\uBC84 \uC5F0\uACB0"]));
1726
2140
  console.log();
1727
2141
  const currentServer = getServer();
1728
2142
  const urlInput = await ask(
@@ -1730,19 +2144,17 @@ async function serverSetup() {
1730
2144
  );
1731
2145
  const url = urlInput || currentServer;
1732
2146
  if (!url) {
1733
- console.log(chalk12.red(" URL\uC774 \uD544\uC694\uD569\uB2C8\uB2E4.\n"));
2147
+ console.log(chalk12.red(" URL \uD544\uC694.\n"));
1734
2148
  return;
1735
2149
  }
1736
2150
  const { setServer: setServer2 } = await Promise.resolve().then(() => (init_store(), store_exports));
1737
2151
  setServer2(url);
1738
- console.log(chalk12.green(` \u2713 \uC11C\uBC84: ${url}
2152
+ console.log(chalk12.green(` \u2713 ${url}
1739
2153
  `));
1740
- console.log(chalk12.bold(" \uB85C\uADF8\uC778"));
1741
- console.log();
1742
2154
  const email = await ask(chalk12.white(" \uC774\uBA54\uC77C: "));
1743
2155
  const password = await ask(chalk12.white(" \uBE44\uBC00\uBC88\uD638: "));
1744
2156
  if (!email || !password) {
1745
- console.log(chalk12.red(" \uC774\uBA54\uC77C\uACFC \uBE44\uBC00\uBC88\uD638\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4.\n"));
2157
+ console.log(chalk12.red(" \uD544\uC694.\n"));
1746
2158
  return;
1747
2159
  }
1748
2160
  try {
@@ -1776,7 +2188,7 @@ async function providerMenu() {
1776
2188
  const providers = getProviders();
1777
2189
  const defaultP = getDefaultProvider();
1778
2190
  console.log();
1779
- console.log(box(["\uD504\uB85C\uBC14\uC774\uB354 \uAD00\uB9AC"], "cyan"));
2191
+ console.log(box(["\uD504\uB85C\uBC14\uC774\uB354 \uAD00\uB9AC"]));
1780
2192
  console.log();
1781
2193
  if (providers.length > 0) {
1782
2194
  for (const p of providers) {
@@ -1785,42 +2197,34 @@ async function providerMenu() {
1785
2197
  }
1786
2198
  console.log();
1787
2199
  } else {
1788
- console.log(chalk12.gray(" \uB4F1\uB85D\uB41C \uD504\uB85C\uBC14\uC774\uB354\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.\n"));
1789
- }
1790
- const items = ["\uC0C8\uB85C \uCD94\uAC00"];
1791
- if (providers.length > 1) items.push("\uAE30\uBCF8 \uBCC0\uACBD");
1792
- if (providers.length > 0) items.push("\uC0AD\uC81C");
1793
- items.push("\uB3CC\uC544\uAC00\uAE30");
1794
- items.forEach((item, i) => {
1795
- console.log(` ${chalk12.cyan(`${i + 1}.`)} ${item}`);
1796
- });
2200
+ console.log(chalk12.gray(" \uC5C6\uC74C\n"));
2201
+ }
2202
+ const opts = ["\uC0C8\uB85C \uCD94\uAC00"];
2203
+ if (providers.length > 1) opts.push("\uAE30\uBCF8 \uBCC0\uACBD");
2204
+ if (providers.length > 0) opts.push("\uC0AD\uC81C");
2205
+ opts.push("\uB3CC\uC544\uAC00\uAE30");
2206
+ opts.forEach((o, i) => console.log(` ${chalk12.cyan(`${i + 1}.`)} ${o}`));
1797
2207
  console.log();
1798
- const choice = await ask(chalk12.cyan(" \u276F "));
1799
- const ci = parseInt(choice);
2208
+ const c = await ask(chalk12.cyan(" \u276F "));
2209
+ const ci = parseInt(c);
1800
2210
  if (ci === 1) {
1801
2211
  await guidedProviderSetup();
1802
- } else if (items[ci - 1] === "\uAE30\uBCF8 \uBCC0\uACBD") {
2212
+ } else if (opts[ci - 1] === "\uAE30\uBCF8 \uBCC0\uACBD") {
1803
2213
  console.log();
1804
- providers.forEach((p, i) => {
1805
- console.log(` ${chalk12.cyan(`${i + 1}.`)} ${p.name} (${p.model})`);
1806
- });
2214
+ providers.forEach((p, i) => console.log(` ${chalk12.cyan(`${i + 1}.`)} ${p.name} (${p.model})`));
1807
2215
  console.log();
1808
- const pc = await ask(chalk12.cyan(" \u276F "));
1809
- const pi = parseInt(pc) - 1;
2216
+ const pi = parseInt(await ask(chalk12.cyan(" \u276F "))) - 1;
1810
2217
  if (pi >= 0 && pi < providers.length) {
1811
2218
  const { setDefaultProvider: setDefaultProvider2 } = await Promise.resolve().then(() => (init_store(), store_exports));
1812
2219
  setDefaultProvider2(providers[pi].id);
1813
2220
  console.log(chalk12.green(` \u2713 \uAE30\uBCF8: ${providers[pi].name}
1814
2221
  `));
1815
2222
  }
1816
- } else if (items[ci - 1] === "\uC0AD\uC81C") {
2223
+ } else if (opts[ci - 1] === "\uC0AD\uC81C") {
1817
2224
  console.log();
1818
- providers.forEach((p, i) => {
1819
- console.log(` ${chalk12.cyan(`${i + 1}.`)} ${p.name} (${p.model})`);
1820
- });
2225
+ providers.forEach((p, i) => console.log(` ${chalk12.cyan(`${i + 1}.`)} ${p.name} (${p.model})`));
1821
2226
  console.log();
1822
- const dc = await ask(chalk12.white(" \uC0AD\uC81C\uD560 \uBC88\uD638: "));
1823
- const di = parseInt(dc) - 1;
2227
+ const di = parseInt(await ask(chalk12.white(" \uC0AD\uC81C \uBC88\uD638: "))) - 1;
1824
2228
  if (di >= 0 && di < providers.length) {
1825
2229
  const { removeProvider: removeProvider2 } = await Promise.resolve().then(() => (init_store(), store_exports));
1826
2230
  removeProvider2(providers[di].id);
@@ -1842,7 +2246,7 @@ var init_home = __esm({
1842
2246
 
1843
2247
  // src/commands/agent.ts
1844
2248
  import chalk13 from "chalk";
1845
- import { createInterface as createInterface6 } from "readline";
2249
+ import { createInterface as createInterface5 } from "readline";
1846
2250
  async function agentRepl() {
1847
2251
  let provider = getDefaultProvider();
1848
2252
  if (!provider) {
@@ -1880,7 +2284,7 @@ async function agentRepl() {
1880
2284
  `${chalk13.gray("/help \uB3C4\uC6C0\uB9D0 \xB7 /home \uD648 \xB7 /exit \uC885\uB8CC")}`
1881
2285
  ]));
1882
2286
  console.log();
1883
- const rl = createInterface6({ input: process.stdin, output: process.stdout });
2287
+ const rl = createInterface5({ input: process.stdin, output: process.stdout });
1884
2288
  const askUser = () => new Promise((resolve) => rl.question(chalk13.cyan.bold(" \u276F "), (a) => resolve(a.trim())));
1885
2289
  process.on("SIGINT", () => {
1886
2290
  console.log(chalk13.gray("\n\uC885\uB8CC\uD569\uB2C8\uB2E4."));
@@ -2236,8 +2640,56 @@ function registerLoginCommand(program2) {
2236
2640
  });
2237
2641
  }
2238
2642
 
2239
- // src/commands/workflow/index.ts
2240
- init_list();
2643
+ // src/commands/workflow/list.ts
2644
+ init_store();
2645
+ init_workflow();
2646
+ init_format();
2647
+ import chalk4 from "chalk";
2648
+ async function workflowList(opts) {
2649
+ requireAuth();
2650
+ try {
2651
+ if (opts.detail) {
2652
+ const workflows = await getWorkflowListDetail();
2653
+ if (!workflows || workflows.length === 0) {
2654
+ console.log(chalk4.yellow("\n\uC6CC\uD06C\uD50C\uB85C\uC6B0\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.\n"));
2655
+ return;
2656
+ }
2657
+ printHeader(`\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uBAA9\uB85D (${workflows.length}\uAC1C)`);
2658
+ console.log();
2659
+ printTable(
2660
+ ["#", "ID", "\uC774\uB984", "\uBC30\uD3EC", "\uC5C5\uB370\uC774\uD2B8"],
2661
+ workflows.map((w, i) => [
2662
+ String(i + 1),
2663
+ (w.workflow_id ?? w.id ?? "-").slice(0, 12),
2664
+ truncate(w.workflow_name ?? "-", 30),
2665
+ w.is_deployed ? chalk4.green("\uBC30\uD3EC\uB428") : chalk4.gray("\uBBF8\uBC30\uD3EC"),
2666
+ formatDate(w.updated_at)
2667
+ ])
2668
+ );
2669
+ } else {
2670
+ const workflows = await listWorkflows();
2671
+ if (!workflows || workflows.length === 0) {
2672
+ console.log(chalk4.yellow("\n\uC6CC\uD06C\uD50C\uB85C\uC6B0\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.\n"));
2673
+ return;
2674
+ }
2675
+ printHeader(`\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uBAA9\uB85D (${workflows.length}\uAC1C)`);
2676
+ console.log();
2677
+ printTable(
2678
+ ["#", "ID", "\uC774\uB984"],
2679
+ workflows.map((w, i) => [
2680
+ String(i + 1),
2681
+ (w.workflow_id ?? w.id ?? "-").slice(0, 12),
2682
+ w.workflow_name ?? "-"
2683
+ ])
2684
+ );
2685
+ }
2686
+ console.log();
2687
+ } catch (err) {
2688
+ const msg = err.message;
2689
+ printError(`\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uBAA9\uB85D \uC870\uD68C \uC2E4\uD328: ${msg}`);
2690
+ process.exit(1);
2691
+ }
2692
+ }
2241
2693
 
2242
2694
  // src/commands/workflow/info.ts
2243
2695
  init_store();
@@ -2277,163 +2729,8 @@ async function workflowInfo(workflowId) {
2277
2729
  }
2278
2730
  }
2279
2731
 
2280
- // src/commands/workflow/run.ts
2281
- init_store();
2282
- init_workflow();
2283
- init_sse();
2284
- init_format();
2285
- import chalk7 from "chalk";
2286
- import { randomUUID } from "crypto";
2287
-
2288
- // src/utils/markdown.ts
2289
- import chalk6 from "chalk";
2290
- var CODE_BLOCK_RE = /```(\w*)\n([\s\S]*?)```/g;
2291
- var INLINE_CODE_RE = /`([^`]+)`/g;
2292
- var BOLD_RE = /\*\*(.+?)\*\*/g;
2293
- var HEADING_RE = /^(#{1,3})\s+(.+)$/gm;
2294
- var LIST_RE = /^(\s*)[-*]\s+(.+)$/gm;
2295
- var LINK_RE = /\[([^\]]+)\]\(([^)]+)\)/g;
2296
- function renderMarkdown(text) {
2297
- let result = text;
2298
- result = result.replace(CODE_BLOCK_RE, (_match, lang, code) => {
2299
- const trimmed = code.trimEnd();
2300
- const header = lang ? chalk6.gray(` \u2500\u2500 ${lang} \u2500\u2500`) : chalk6.gray(" \u2500\u2500 code \u2500\u2500");
2301
- const lines = trimmed.split("\n").map((l) => chalk6.white(` ${l}`)).join("\n");
2302
- return `
2303
- ${header}
2304
- ${lines}
2305
- ${chalk6.gray(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500")}
2306
- `;
2307
- });
2308
- result = result.replace(INLINE_CODE_RE, (_m, code) => chalk6.cyan(`\`${code}\``));
2309
- result = result.replace(BOLD_RE, (_m, text2) => chalk6.bold(text2));
2310
- result = result.replace(HEADING_RE, (_m, hashes, text2) => {
2311
- if (hashes.length === 1) return chalk6.bold.underline(text2);
2312
- if (hashes.length === 2) return chalk6.bold(text2);
2313
- return chalk6.bold.dim(text2);
2314
- });
2315
- result = result.replace(LIST_RE, (_m, indent, text2) => `${indent}${chalk6.cyan("\u2022")} ${text2}`);
2316
- result = result.replace(LINK_RE, (_m, label, url) => `${chalk6.blue.underline(label)} ${chalk6.gray(`(${url})`)}`);
2317
- return result;
2318
- }
2319
-
2320
- // src/commands/workflow/run.ts
2321
- async function workflowRun(workflowId, input, opts) {
2322
- const auth = requireAuth();
2323
- let workflowName = workflowId;
2324
- try {
2325
- const detail = await getWorkflowDetail(workflowId);
2326
- workflowName = detail.workflow_name ?? workflowId;
2327
- } catch {
2328
- }
2329
- if (!input) {
2330
- if (opts.interactive || !process.stdin.isTTY) {
2331
- const { createInterface: createInterface8 } = await import("readline");
2332
- const rl = createInterface8({ input: process.stdin, output: process.stdout });
2333
- input = await new Promise((resolve) => {
2334
- rl.question(chalk7.cyan("\uC785\uB825> "), (answer) => {
2335
- rl.close();
2336
- resolve(answer.trim());
2337
- });
2338
- });
2339
- } else {
2340
- printError("\uC785\uB825\uAC12\uC774 \uD544\uC694\uD569\uB2C8\uB2E4. \uC0AC\uC6A9\uBC95:");
2341
- console.log(' xgen workflow run <id> "\uC785\uB825 \uD14D\uC2A4\uFFFD\uFFFD\uFFFD"');
2342
- console.log(" xgen workflow run -i <id>");
2343
- process.exit(1);
2344
- }
2345
- }
2346
- if (!input) {
2347
- printError("\uC785\uB825\uAC12\uC774 \uBE44\uC5B4\uC788\uC2B5\uB2C8\uB2E4");
2348
- process.exit(1);
2349
- }
2350
- const interactionId = `cli_${randomUUID().slice(0, 8)}`;
2351
- printHeader(`\uC2E4\uD589: ${workflowName}`);
2352
- printInfo(`\uC785\uB825: ${input}`);
2353
- console.log();
2354
- try {
2355
- const stream = await executeWorkflowStream({
2356
- workflow_id: workflowId,
2357
- workflow_name: workflowName,
2358
- input_data: input,
2359
- interaction_id: interactionId
2360
- });
2361
- let hasOutput = false;
2362
- let fullResponse = "";
2363
- await parseSSEStream(
2364
- stream,
2365
- (event) => {
2366
- switch (event.type) {
2367
- case "token":
2368
- if (event.content) {
2369
- if (!hasOutput) {
2370
- hasOutput = true;
2371
- console.log();
2372
- }
2373
- process.stdout.write(event.content);
2374
- fullResponse += event.content;
2375
- }
2376
- break;
2377
- case "log":
2378
- if (opts.logs && event.content) {
2379
- process.stderr.write(chalk7.gray(`[LOG] ${event.content}
2380
- `));
2381
- }
2382
- break;
2383
- case "node_status":
2384
- if (opts.logs) {
2385
- const nodeName = event.node_name ?? event.node_id ?? "?";
2386
- const status = event.status ?? "?";
2387
- process.stderr.write(
2388
- chalk7.gray(`[\uB178\uB4DC] ${nodeName}: ${status}
2389
- `)
2390
- );
2391
- }
2392
- break;
2393
- case "tool":
2394
- if (opts.logs) {
2395
- process.stderr.write(chalk7.gray(`[\uB3C4\uAD6C] ${JSON.stringify(event.data)}
2396
- `));
2397
- }
2398
- break;
2399
- case "complete":
2400
- break;
2401
- case "error":
2402
- console.log();
2403
- printError(event.error ?? event.content ?? "\uC54C \uC218 \uC5C6\uB294 \uC624\uB958");
2404
- break;
2405
- default:
2406
- if (event.content) {
2407
- if (!hasOutput) {
2408
- process.stdout.write(chalk7.green("\uC751\uB2F5: "));
2409
- hasOutput = true;
2410
- }
2411
- process.stdout.write(event.content);
2412
- }
2413
- }
2414
- },
2415
- () => {
2416
- if (hasOutput) {
2417
- console.log();
2418
- if (fullResponse.includes("```") || fullResponse.includes("**")) {
2419
- console.log(chalk7.gray("\u2500".repeat(40)));
2420
- console.log(renderMarkdown(fullResponse));
2421
- }
2422
- }
2423
- console.log();
2424
- console.log(chalk7.gray(`\uC138\uC158: ${interactionId}`));
2425
- },
2426
- (err) => {
2427
- console.log();
2428
- printError(`\uC2A4\uD2B8\uB9AC\uBC0D \uC624\uB958: ${err.message}`);
2429
- }
2430
- );
2431
- } catch (err) {
2432
- const msg = err?.response?.data?.detail ?? err.message;
2433
- printError(`\uC2E4\uD589 \uC2E4\uD328: ${msg}`);
2434
- process.exit(1);
2435
- }
2436
- }
2732
+ // src/commands/workflow/index.ts
2733
+ init_run();
2437
2734
 
2438
2735
  // src/commands/workflow/history.ts
2439
2736
  init_store();
@@ -2489,43 +2786,9 @@ init_agent();
2489
2786
 
2490
2787
  // src/commands/doc.ts
2491
2788
  init_store();
2492
- import chalk14 from "chalk";
2493
-
2494
- // src/api/document.ts
2495
- init_client();
2496
- import { createReadStream, statSync } from "fs";
2497
- import { basename } from "path";
2498
- async function listDocuments(collectionId) {
2499
- const client2 = getClient();
2500
- const params = {};
2501
- if (collectionId) params.collection_id = collectionId;
2502
- const res = await client2.get("/api/documents/list", { params });
2503
- return res.data.documents ?? res.data ?? [];
2504
- }
2505
- async function uploadDocument(filePath, collectionId, name) {
2506
- const client2 = getClient();
2507
- const stat = statSync(filePath);
2508
- const fileName = name || basename(filePath);
2509
- const FormData = (await import("buffer")).Blob ? globalThis.FormData : null;
2510
- if (!FormData) throw new Error("FormData not available");
2511
- const form = new FormData();
2512
- const fileBlob = new Blob([createReadStream(filePath)]);
2513
- form.append("file", fileBlob, fileName);
2514
- if (collectionId) form.append("collection_id", collectionId);
2515
- const res = await client2.post("/api/documents/upload", form, {
2516
- headers: { "Content-Type": "multipart/form-data" },
2517
- maxBodyLength: stat.size + 1024 * 1024
2518
- });
2519
- return res.data;
2520
- }
2521
- async function getDocumentInfo(docId) {
2522
- const client2 = getClient();
2523
- const res = await client2.get(`/api/documents/${docId}`);
2524
- return res.data;
2525
- }
2526
-
2527
- // src/commands/doc.ts
2789
+ init_document();
2528
2790
  init_format();
2791
+ import chalk14 from "chalk";
2529
2792
  function registerDocCommand(program2) {
2530
2793
  const doc = program2.command("doc").description("\uBB38\uC11C \uAD00\uB9AC");
2531
2794
  doc.command("list").alias("ls").description("\uBB38\uC11C \uBAA9\uB85D \uC870\uD68C").option("-c, --collection <id>", "\uCEEC\uB809\uC158 ID").action(async (opts) => {
@@ -2579,38 +2842,10 @@ function registerDocCommand(program2) {
2579
2842
 
2580
2843
  // src/commands/ontology.ts
2581
2844
  init_store();
2582
- import chalk15 from "chalk";
2583
- import { createInterface as createInterface7 } from "readline";
2584
-
2585
- // src/api/ontology.ts
2586
- init_client();
2587
- async function queryGraphRAG(query, graphId, opts) {
2588
- const client2 = getClient();
2589
- const res = await client2.post("/api/graph-rag", {
2590
- query,
2591
- graph_id: graphId,
2592
- use_scs: opts?.scs ?? true
2593
- });
2594
- return res.data;
2595
- }
2596
- async function queryGraphRAGMultiTurn(query, sessionId, graphId, opts) {
2597
- const client2 = getClient();
2598
- const res = await client2.post("/api/graph-rag/multi-turn", {
2599
- query,
2600
- session_id: sessionId,
2601
- graph_id: graphId,
2602
- max_turns: opts?.maxTurns ?? 5
2603
- });
2604
- return res.data;
2605
- }
2606
- async function getGraphStats(graphId) {
2607
- const client2 = getClient();
2608
- const res = await client2.get(`/api/graph/${graphId}/stats`);
2609
- return res.data;
2610
- }
2611
-
2612
- // src/commands/ontology.ts
2845
+ init_ontology();
2613
2846
  init_format();
2847
+ import chalk15 from "chalk";
2848
+ import { createInterface as createInterface6 } from "readline";
2614
2849
  import { randomUUID as randomUUID3 } from "crypto";
2615
2850
  function registerOntologyCommand(program2) {
2616
2851
  const ont = program2.command("ontology").alias("ont").description("\uC628\uD1A8\uB85C\uC9C0 GraphRAG \uC9C8\uC758");
@@ -2641,7 +2876,7 @@ function registerOntologyCommand(program2) {
2641
2876
  const sessionId = randomUUID3();
2642
2877
  printHeader("Ontology Chat");
2643
2878
  console.log(chalk15.gray("\uBA40\uD2F0\uD134 GraphRAG \uB300\uD654. exit\uB85C \uC885\uB8CC.\n"));
2644
- const rl = createInterface7({ input: process.stdin, output: process.stdout });
2879
+ const rl = createInterface6({ input: process.stdin, output: process.stdout });
2645
2880
  const ask2 = () => new Promise((resolve) => rl.question(chalk15.green("\u276F "), (a) => resolve(a.trim())));
2646
2881
  while (true) {
2647
2882
  const input = await ask2();