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 +739 -504
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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/
|
|
841
|
+
// src/utils/ui.ts
|
|
710
842
|
import chalk10 from "chalk";
|
|
711
843
|
import { createInterface as createInterface3 } from "readline";
|
|
712
|
-
|
|
713
|
-
|
|
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
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
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.
|
|
752
|
-
|
|
753
|
-
if (!
|
|
754
|
-
|
|
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(
|
|
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
|
|
767
|
-
console.log(` ${
|
|
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(` ${
|
|
965
|
+
console.log(` ${chalk11.cyan(`${String(preset.models.length + 1).padStart(2)}.`)} \uC9C1\uC811 \uC785\uB825`);
|
|
770
966
|
console.log();
|
|
771
|
-
const
|
|
772
|
-
|
|
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 (
|
|
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
|
|
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
|
|
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(
|
|
789
|
-
\u2713 \
|
|
790
|
-
console.log(
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
814
|
-
console.log(
|
|
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(
|
|
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
|
|
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(
|
|
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(
|
|
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 ?
|
|
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
|
-
|
|
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
|
-
|
|
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: [
|
|
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
|
|
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: [
|
|
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
|
|
1083
|
+
keyHint: "https://aistudio.google.com/apikey",
|
|
1084
|
+
envKey: "GEMINI_API_KEY"
|
|
890
1085
|
},
|
|
891
1086
|
{
|
|
892
|
-
label: "
|
|
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: [
|
|
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 \
|
|
1120
|
+
keyHint: "https://ollama.ai \uC124\uCE58 \uD6C4 ollama pull <\uBAA8\uB378>"
|
|
899
1121
|
},
|
|
900
1122
|
{
|
|
901
|
-
label: "
|
|
902
|
-
type: "
|
|
903
|
-
baseUrl: "https://api.
|
|
904
|
-
defaultModel: "
|
|
905
|
-
models: [
|
|
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://
|
|
1181
|
+
keyHint: "https://platform.deepseek.com/api_keys",
|
|
1182
|
+
envKey: "DEEPSEEK_API_KEY"
|
|
908
1183
|
},
|
|
909
1184
|
{
|
|
910
|
-
label: "
|
|
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/
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
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
|
|
1855
|
+
return res.data;
|
|
1564
1856
|
}
|
|
1565
|
-
function
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
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
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
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
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
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
|
|
1587
|
-
const
|
|
1588
|
-
|
|
1589
|
-
|
|
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
|
-
|
|
1601
|
-
|
|
1602
|
-
"
|
|
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
|
-
|
|
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
|
-
|
|
1621
|
-
|
|
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.
|
|
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
|
-
|
|
1646
|
-
|
|
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
|
-
|
|
1667
|
-
|
|
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
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
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
|
-
|
|
1677
|
-
|
|
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
|
|
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
|
-
|
|
1695
|
-
|
|
1696
|
-
console.log(
|
|
1697
|
-
|
|
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(`
|
|
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"
|
|
1703
|
-
|
|
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
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
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
|
-
|
|
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"]
|
|
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
|
|
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
|
|
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(" \
|
|
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"]
|
|
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(" \
|
|
1789
|
-
}
|
|
1790
|
-
const
|
|
1791
|
-
if (providers.length > 1)
|
|
1792
|
-
if (providers.length > 0)
|
|
1793
|
-
|
|
1794
|
-
|
|
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
|
|
1799
|
-
const ci = parseInt(
|
|
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 (
|
|
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
|
|
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 (
|
|
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
|
|
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
|
|
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 =
|
|
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/
|
|
2240
|
-
|
|
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/
|
|
2281
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
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();
|