openxgen 0.6.1 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1921 -2227
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -426,465 +426,171 @@ var init_workflow = __esm({
|
|
|
426
426
|
}
|
|
427
427
|
});
|
|
428
428
|
|
|
429
|
-
// src/utils/
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
onEvent(event);
|
|
451
|
-
} catch {
|
|
452
|
-
onEvent({ type: "token", content: data });
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
});
|
|
456
|
-
stream.on("end", () => {
|
|
457
|
-
if (buffer.trim()) {
|
|
458
|
-
const lines = buffer.split("\n");
|
|
459
|
-
for (const line of lines) {
|
|
460
|
-
if (line.startsWith("data: ")) {
|
|
461
|
-
try {
|
|
462
|
-
const event = JSON.parse(line.slice(6));
|
|
463
|
-
onEvent(event);
|
|
464
|
-
} catch {
|
|
465
|
-
onEvent({ type: "token", content: line.slice(6) });
|
|
466
|
-
}
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
}
|
|
470
|
-
onDone?.();
|
|
471
|
-
resolve();
|
|
472
|
-
});
|
|
473
|
-
stream.on("error", (err) => {
|
|
474
|
-
onError?.(err);
|
|
475
|
-
reject(err);
|
|
429
|
+
// src/utils/ui.ts
|
|
430
|
+
import chalk10 from "chalk";
|
|
431
|
+
import { createInterface as createInterface3 } from "readline";
|
|
432
|
+
function box(lines, color = "cyan") {
|
|
433
|
+
const c = chalk10[color];
|
|
434
|
+
const inner = W - 4;
|
|
435
|
+
const top = c(" \u256D" + "\u2500".repeat(inner) + "\u256E");
|
|
436
|
+
const bot = c(" \u2570" + "\u2500".repeat(inner) + "\u256F");
|
|
437
|
+
const body = lines.map((line) => {
|
|
438
|
+
const clean = line.replace(/\x1b\[[0-9;]*m/g, "");
|
|
439
|
+
const pad = Math.max(0, inner - clean.length);
|
|
440
|
+
return c(" \u2502 ") + line + " ".repeat(pad) + c(" \u2502");
|
|
441
|
+
});
|
|
442
|
+
return [top, ...body, bot].join("\n");
|
|
443
|
+
}
|
|
444
|
+
function ask(question) {
|
|
445
|
+
return new Promise((resolve) => {
|
|
446
|
+
const rl = createInterface3({ input: process.stdin, output: process.stdout });
|
|
447
|
+
rl.question(question, (answer) => {
|
|
448
|
+
rl.close();
|
|
449
|
+
resolve(answer.trim());
|
|
476
450
|
});
|
|
477
451
|
});
|
|
478
452
|
}
|
|
479
|
-
|
|
480
|
-
|
|
453
|
+
function welcome() {
|
|
454
|
+
const logo = chalk10.cyan(`
|
|
455
|
+
\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588 \u2588\u2588
|
|
456
|
+
\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588 \u2588\u2588
|
|
457
|
+
\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588
|
|
458
|
+
\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588
|
|
459
|
+
\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588`) + chalk10.white.bold(`
|
|
460
|
+
\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588 \u2588\u2588
|
|
461
|
+
\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588 \u2588\u2588
|
|
462
|
+
\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588
|
|
463
|
+
\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588
|
|
464
|
+
\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588`);
|
|
465
|
+
return logo;
|
|
466
|
+
}
|
|
467
|
+
var W;
|
|
468
|
+
var init_ui = __esm({
|
|
469
|
+
"src/utils/ui.ts"() {
|
|
481
470
|
"use strict";
|
|
471
|
+
W = Math.min(process.stdout.columns || 60, 70);
|
|
482
472
|
}
|
|
483
473
|
});
|
|
484
474
|
|
|
485
|
-
// src/commands/
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
${chalk9.cyan("/info")} \uD604\uC7AC \uC5F0\uACB0 \uC815\uBCF4
|
|
497
|
-
${chalk9.cyan("/help")} \uC774 \uB3C4\uC6C0\uB9D0
|
|
498
|
-
${chalk9.cyan("/exit")} \uC885\uB8CC (Ctrl+C\uB3C4 \uAC00\uB2A5)
|
|
499
|
-
`);
|
|
475
|
+
// src/commands/provider.ts
|
|
476
|
+
var provider_exports = {};
|
|
477
|
+
__export(provider_exports, {
|
|
478
|
+
guidedProviderSetup: () => guidedProviderSetup,
|
|
479
|
+
registerProviderCommand: () => registerProviderCommand
|
|
480
|
+
});
|
|
481
|
+
import chalk11 from "chalk";
|
|
482
|
+
import OpenAI from "openai";
|
|
483
|
+
function detectEnvKey(preset) {
|
|
484
|
+
if (!preset.envKey) return null;
|
|
485
|
+
return process.env[preset.envKey] ?? null;
|
|
500
486
|
}
|
|
501
|
-
async function
|
|
502
|
-
|
|
503
|
-
|
|
487
|
+
async function guidedProviderSetup() {
|
|
488
|
+
console.log();
|
|
489
|
+
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.")]));
|
|
490
|
+
console.log();
|
|
491
|
+
console.log(chalk11.bold(" \uD504\uB85C\uBC14\uC774\uB354 \uC120\uD0DD:\n"));
|
|
492
|
+
PRESETS.forEach((p, i) => {
|
|
493
|
+
const envDetected = detectEnvKey(p);
|
|
494
|
+
const envTag = envDetected ? chalk11.green(" [\uD0A4 \uAC10\uC9C0\uB428]") : "";
|
|
495
|
+
const free = !p.needsKey ? chalk11.green(" [\uBB34\uB8CC]") : "";
|
|
496
|
+
console.log(` ${chalk11.cyan(`${String(i + 1).padStart(2)}.`)} ${p.label}${free}${envTag}`);
|
|
497
|
+
console.log(` ${chalk11.gray(p.defaultModel)}`);
|
|
504
498
|
});
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
const
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
workflows = await listWorkflows();
|
|
512
|
-
} catch {
|
|
513
|
-
printError("\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uBAA9\uB85D\uC744 \uBD88\uB7EC\uC62C \uC218 \uC5C6\uC2B5\uB2C8\uB2E4");
|
|
514
|
-
process.exit(1);
|
|
515
|
-
}
|
|
516
|
-
if (workflows.length === 0) {
|
|
517
|
-
printError("\uC0AC\uC6A9 \uAC00\uB2A5\uD55C \uC6CC\uD06C\uD50C\uB85C\uC6B0\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4");
|
|
518
|
-
process.exit(1);
|
|
499
|
+
console.log();
|
|
500
|
+
const choice = await ask(chalk11.cyan(" \uBC88\uD638: "));
|
|
501
|
+
const idx = parseInt(choice) - 1;
|
|
502
|
+
if (isNaN(idx) || idx < 0 || idx >= PRESETS.length) {
|
|
503
|
+
console.log(chalk11.red(" \uC798\uBABB\uB41C \uC120\uD0DD.\n"));
|
|
504
|
+
return null;
|
|
519
505
|
}
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
current = found ?? { id: workflowId, workflow_name: workflowId };
|
|
524
|
-
} else {
|
|
525
|
-
console.log(CHAT_BANNER);
|
|
526
|
-
console.log(chalk9.gray(` \uC11C\uBC84: ${server} | \uC0AC\uC6A9\uC790: ${auth.username}
|
|
506
|
+
const preset = PRESETS[idx];
|
|
507
|
+
console.log(chalk11.green(`
|
|
508
|
+
\u2713 ${preset.label}
|
|
527
509
|
`));
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
510
|
+
let apiKey = "";
|
|
511
|
+
if (preset.needsKey) {
|
|
512
|
+
const envKey = detectEnvKey(preset);
|
|
513
|
+
if (envKey) {
|
|
514
|
+
console.log(chalk11.green(` API Key \uC790\uB3D9 \uAC10\uC9C0 (${preset.envKey})`));
|
|
515
|
+
const useEnv = await ask(chalk11.white(` \uC774 \uD0A4\uB97C \uC0AC\uC6A9\uD560\uAE4C\uC694? (Y/n): `));
|
|
516
|
+
if (useEnv.toLowerCase() !== "n") {
|
|
517
|
+
apiKey = envKey;
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
if (!apiKey) {
|
|
521
|
+
console.log(chalk11.gray(` \uBC1C\uAE09: ${preset.keyHint}
|
|
522
|
+
`));
|
|
523
|
+
apiKey = await ask(chalk11.white(" API Key: "));
|
|
524
|
+
if (!apiKey) {
|
|
525
|
+
console.log(chalk11.red(" API Key \uD544\uC694.\n"));
|
|
526
|
+
return null;
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
let baseUrl = preset.baseUrl;
|
|
531
|
+
if (preset.label === "\uAE30\uD0C0 (OpenAI \uD638\uD658 \uC11C\uBC84)") {
|
|
532
|
+
baseUrl = await ask(chalk11.white(" Base URL: "));
|
|
533
|
+
if (!baseUrl) {
|
|
534
|
+
console.log(chalk11.red(" URL \uD544\uC694.\n"));
|
|
535
|
+
return null;
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
let model = preset.defaultModel;
|
|
539
|
+
if (preset.models.length > 0) {
|
|
540
|
+
console.log(chalk11.bold("\n \uBAA8\uB378:\n"));
|
|
541
|
+
const defaultIdx = preset.models.indexOf(preset.defaultModel);
|
|
542
|
+
preset.models.forEach((m, i) => {
|
|
543
|
+
const tag = i === defaultIdx ? chalk11.green(" \u2190 \uCD94\uCC9C") : "";
|
|
544
|
+
console.log(` ${chalk11.cyan(`${String(i + 1).padStart(2)}.`)} ${m}${tag}`);
|
|
531
545
|
});
|
|
546
|
+
console.log(` ${chalk11.cyan(`${String(preset.models.length + 1).padStart(2)}.`)} \uC9C1\uC811 \uC785\uB825`);
|
|
532
547
|
console.log();
|
|
533
|
-
const
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
const idx = parseInt(answer.trim()) - 1;
|
|
537
|
-
if (isNaN(idx) || idx < 0 || idx >= workflows.length) {
|
|
538
|
-
current = workflows[0];
|
|
548
|
+
const mc = await ask(chalk11.cyan(` \uBC88\uD638 [${defaultIdx + 1}]: `));
|
|
549
|
+
if (!mc || mc === String(defaultIdx + 1)) {
|
|
550
|
+
model = preset.defaultModel;
|
|
539
551
|
} else {
|
|
540
|
-
|
|
552
|
+
const mi = parseInt(mc) - 1;
|
|
553
|
+
if (mi >= 0 && mi < preset.models.length) {
|
|
554
|
+
model = preset.models[mi];
|
|
555
|
+
} else if (parseInt(mc) === preset.models.length + 1) {
|
|
556
|
+
model = await ask(chalk11.white(" \uBAA8\uB378\uBA85: ")) || preset.defaultModel;
|
|
557
|
+
}
|
|
541
558
|
}
|
|
559
|
+
} else if (preset.label === "\uAE30\uD0C0 (OpenAI \uD638\uD658 \uC11C\uBC84)") {
|
|
560
|
+
model = await ask(chalk11.white(` \uBAA8\uB378\uBA85 [${preset.defaultModel}]: `)) || preset.defaultModel;
|
|
542
561
|
}
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
console.clear();
|
|
576
|
-
console.log(chalk9.white.bold(` ${current.workflow_name}`));
|
|
577
|
-
console.log(chalk9.cyan("\u2500".repeat(42)));
|
|
578
|
-
break;
|
|
579
|
-
case "workflows":
|
|
580
|
-
case "wf":
|
|
581
|
-
console.log();
|
|
582
|
-
workflows.forEach((w, i) => {
|
|
583
|
-
const marker = w.id === current.id ? chalk9.green("\u25B8") : " ";
|
|
584
|
-
console.log(` ${marker} ${chalk9.cyan(String(i + 1).padStart(2))} ${w.workflow_name}`);
|
|
585
|
-
});
|
|
586
|
-
console.log(chalk9.gray("\n /switch <\uBC88\uD638> \uB85C \uC804\uD658\n"));
|
|
587
|
-
break;
|
|
588
|
-
case "switch":
|
|
589
|
-
case "sw": {
|
|
590
|
-
const num = parseInt(args[0]);
|
|
591
|
-
if (isNaN(num) || num < 1 || num > workflows.length) {
|
|
592
|
-
console.log(chalk9.yellow(` 1~${workflows.length} \uC0AC\uC774 \uBC88\uD638\uB97C \uC785\uB825\uD558\uC138\uC694`));
|
|
593
|
-
} else {
|
|
594
|
-
current = workflows[num - 1];
|
|
595
|
-
turnCount = 0;
|
|
596
|
-
history.length = 0;
|
|
597
|
-
console.log(chalk9.green(`
|
|
598
|
-
\uC804\uD658: ${current.workflow_name}
|
|
599
|
-
`));
|
|
600
|
-
}
|
|
601
|
-
break;
|
|
602
|
-
}
|
|
603
|
-
case "history":
|
|
604
|
-
case "hist":
|
|
605
|
-
if (history.length === 0) {
|
|
606
|
-
console.log(chalk9.gray(" \uB300\uD654 \uC774\uB825\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.\n"));
|
|
607
|
-
} else {
|
|
608
|
-
console.log();
|
|
609
|
-
for (const h of history) {
|
|
610
|
-
const label = h.role === "user" ? chalk9.cyan("\uB098") : chalk9.green("AI");
|
|
611
|
-
const text = h.content.length > 80 ? h.content.slice(0, 80) + "..." : h.content;
|
|
612
|
-
console.log(` ${label}: ${text}`);
|
|
613
|
-
}
|
|
614
|
-
console.log();
|
|
615
|
-
}
|
|
616
|
-
break;
|
|
617
|
-
case "info":
|
|
618
|
-
console.log(`
|
|
619
|
-
${chalk9.gray("\uC11C\uBC84:")} ${server}
|
|
620
|
-
${chalk9.gray("\uC0AC\uC6A9\uC790:")} ${auth.username}
|
|
621
|
-
${chalk9.gray("\uC6CC\uD06C\uD50C\uB85C\uC6B0:")} ${current.workflow_name}
|
|
622
|
-
${chalk9.gray("\uC138\uC158:")} ${sessionId}
|
|
623
|
-
${chalk9.gray("\uD134:")} ${turnCount}
|
|
624
|
-
`);
|
|
625
|
-
break;
|
|
626
|
-
default:
|
|
627
|
-
console.log(chalk9.yellow(` \uC54C \uC218 \uC5C6\uB294 \uCEE4\uB9E8\uB4DC: /${cmd}. /help \uCC38\uACE0`));
|
|
628
|
-
}
|
|
629
|
-
rl.prompt();
|
|
630
|
-
return;
|
|
631
|
-
}
|
|
632
|
-
turnCount++;
|
|
633
|
-
const interactionId = `${sessionId}_t${turnCount}`;
|
|
634
|
-
history.push({ role: "user", content: input });
|
|
635
|
-
process.stdout.write(chalk9.gray(" thinking..."));
|
|
636
|
-
try {
|
|
637
|
-
const stream = await executeWorkflowStream({
|
|
638
|
-
workflow_id: current.id,
|
|
639
|
-
workflow_name: current.workflow_name,
|
|
640
|
-
input_data: input,
|
|
641
|
-
interaction_id: interactionId
|
|
642
|
-
});
|
|
643
|
-
process.stdout.write("\r" + " ".repeat(20) + "\r");
|
|
644
|
-
let fullResponse = "";
|
|
645
|
-
let hasOutput = false;
|
|
646
|
-
await parseSSEStream(
|
|
647
|
-
stream,
|
|
648
|
-
(event) => {
|
|
649
|
-
if ((event.type === "token" || !event.type) && event.content) {
|
|
650
|
-
if (!hasOutput) {
|
|
651
|
-
hasOutput = true;
|
|
652
|
-
console.log();
|
|
653
|
-
}
|
|
654
|
-
process.stdout.write(event.content);
|
|
655
|
-
fullResponse += event.content;
|
|
656
|
-
} else if (event.type === "error") {
|
|
657
|
-
process.stdout.write("\r" + " ".repeat(20) + "\r");
|
|
658
|
-
printError(event.error ?? event.content ?? "\uC624\uB958");
|
|
659
|
-
}
|
|
660
|
-
},
|
|
661
|
-
() => {
|
|
662
|
-
if (hasOutput) {
|
|
663
|
-
console.log();
|
|
664
|
-
console.log();
|
|
665
|
-
}
|
|
666
|
-
if (fullResponse) {
|
|
667
|
-
history.push({ role: "assistant", content: fullResponse });
|
|
668
|
-
}
|
|
669
|
-
},
|
|
670
|
-
(err) => {
|
|
671
|
-
process.stdout.write("\r" + " ".repeat(20) + "\r");
|
|
672
|
-
printError(`\uC2A4\uD2B8\uB9AC\uBC0D \uC624\uB958: ${err.message}`);
|
|
673
|
-
}
|
|
674
|
-
);
|
|
675
|
-
} catch (err) {
|
|
676
|
-
process.stdout.write("\r" + " ".repeat(20) + "\r");
|
|
677
|
-
const msg = err?.response?.data?.detail ?? err.message;
|
|
678
|
-
printError(`\uC2E4\uD589 \uC2E4\uD328: ${msg}`);
|
|
679
|
-
}
|
|
680
|
-
rl.prompt();
|
|
681
|
-
};
|
|
682
|
-
rl.setPrompt(getPrompt());
|
|
683
|
-
rl.prompt();
|
|
684
|
-
rl.on("line", (line) => {
|
|
685
|
-
processInput(line).then(() => {
|
|
686
|
-
});
|
|
687
|
-
});
|
|
688
|
-
rl.on("close", () => {
|
|
689
|
-
console.log(chalk9.gray("\n \uC885\uB8CC\uD569\uB2C8\uB2E4.\n"));
|
|
690
|
-
process.exit(0);
|
|
691
|
-
});
|
|
692
|
-
process.on("SIGINT", () => {
|
|
693
|
-
console.log(chalk9.gray("\n \uC885\uB8CC\uD569\uB2C8\uB2E4.\n"));
|
|
694
|
-
process.exit(0);
|
|
695
|
-
});
|
|
696
|
-
}
|
|
697
|
-
function registerChatCommand(program2) {
|
|
698
|
-
program2.command("chat [workflow-id]").description("\uC778\uD130\uB799\uD2F0\uBE0C \uB300\uD654 \uBAA8\uB4DC").action((workflowId) => chat(workflowId));
|
|
699
|
-
}
|
|
700
|
-
var CHAT_BANNER;
|
|
701
|
-
var init_chat = __esm({
|
|
702
|
-
"src/commands/chat.ts"() {
|
|
703
|
-
"use strict";
|
|
704
|
-
init_store();
|
|
705
|
-
init_workflow();
|
|
706
|
-
init_sse();
|
|
707
|
-
init_format();
|
|
708
|
-
CHAT_BANNER = `
|
|
709
|
-
${chalk9.cyan("\u256D\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256E")}
|
|
710
|
-
${chalk9.cyan("\u2502")} ${chalk9.white.bold("XGEN")} ${chalk9.gray("\u2014 \uC6CC\uD06C\uD50C\uB85C\uC6B0 AI \uD130\uBBF8\uB110")} ${chalk9.cyan("\u2502")}
|
|
711
|
-
${chalk9.cyan("\u2502")} ${chalk9.gray("/help \uB3C4\uC6C0\uB9D0 /workflows \uC804\uD658 /exit")} ${chalk9.cyan("\u2502")}
|
|
712
|
-
${chalk9.cyan("\u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256F")}`;
|
|
713
|
-
}
|
|
714
|
-
});
|
|
715
|
-
|
|
716
|
-
// src/utils/ui.ts
|
|
717
|
-
import chalk10 from "chalk";
|
|
718
|
-
import { createInterface as createInterface3 } from "readline";
|
|
719
|
-
function box(lines, color = "cyan") {
|
|
720
|
-
const c = chalk10[color];
|
|
721
|
-
const inner = W - 4;
|
|
722
|
-
const top = c(" \u256D" + "\u2500".repeat(inner) + "\u256E");
|
|
723
|
-
const bot = c(" \u2570" + "\u2500".repeat(inner) + "\u256F");
|
|
724
|
-
const body = lines.map((line) => {
|
|
725
|
-
const clean = line.replace(/\x1b\[[0-9;]*m/g, "");
|
|
726
|
-
const pad = Math.max(0, inner - clean.length);
|
|
727
|
-
return c(" \u2502 ") + line + " ".repeat(pad) + c(" \u2502");
|
|
728
|
-
});
|
|
729
|
-
return [top, ...body, bot].join("\n");
|
|
730
|
-
}
|
|
731
|
-
function divider(label) {
|
|
732
|
-
if (label) {
|
|
733
|
-
const rest = W - label.length - 6;
|
|
734
|
-
return chalk10.gray(` \u2500\u2500 ${label} ${"\u2500".repeat(Math.max(0, rest))}`);
|
|
735
|
-
}
|
|
736
|
-
return chalk10.gray(" " + "\u2500".repeat(W - 2));
|
|
737
|
-
}
|
|
738
|
-
function statusDot(active, label, detail) {
|
|
739
|
-
const dot = active ? chalk10.green("\u25CF") : chalk10.gray("\u25CB");
|
|
740
|
-
const d = detail ? chalk10.gray(` ${detail}`) : "";
|
|
741
|
-
return ` ${dot} ${label}${d}`;
|
|
742
|
-
}
|
|
743
|
-
function ask(question) {
|
|
744
|
-
return new Promise((resolve) => {
|
|
745
|
-
const rl = createInterface3({ input: process.stdin, output: process.stdout });
|
|
746
|
-
rl.question(question, (answer) => {
|
|
747
|
-
rl.close();
|
|
748
|
-
resolve(answer.trim());
|
|
749
|
-
});
|
|
750
|
-
});
|
|
751
|
-
}
|
|
752
|
-
function welcome() {
|
|
753
|
-
const logo = chalk10.cyan(`
|
|
754
|
-
\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588 \u2588\u2588
|
|
755
|
-
\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588 \u2588\u2588
|
|
756
|
-
\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588
|
|
757
|
-
\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588
|
|
758
|
-
\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588`) + chalk10.white.bold(`
|
|
759
|
-
\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588 \u2588\u2588
|
|
760
|
-
\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588 \u2588\u2588
|
|
761
|
-
\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588
|
|
762
|
-
\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588
|
|
763
|
-
\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588`);
|
|
764
|
-
return logo;
|
|
765
|
-
}
|
|
766
|
-
var W;
|
|
767
|
-
var init_ui = __esm({
|
|
768
|
-
"src/utils/ui.ts"() {
|
|
769
|
-
"use strict";
|
|
770
|
-
W = Math.min(process.stdout.columns || 60, 70);
|
|
771
|
-
}
|
|
772
|
-
});
|
|
773
|
-
|
|
774
|
-
// src/commands/provider.ts
|
|
775
|
-
import chalk11 from "chalk";
|
|
776
|
-
import OpenAI from "openai";
|
|
777
|
-
function detectEnvKey(preset) {
|
|
778
|
-
if (!preset.envKey) return null;
|
|
779
|
-
return process.env[preset.envKey] ?? null;
|
|
780
|
-
}
|
|
781
|
-
async function guidedProviderSetup() {
|
|
782
|
-
console.log();
|
|
783
|
-
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.")]));
|
|
784
|
-
console.log();
|
|
785
|
-
console.log(chalk11.bold(" \uD504\uB85C\uBC14\uC774\uB354 \uC120\uD0DD:\n"));
|
|
786
|
-
PRESETS.forEach((p, i) => {
|
|
787
|
-
const envDetected = detectEnvKey(p);
|
|
788
|
-
const envTag = envDetected ? chalk11.green(" [\uD0A4 \uAC10\uC9C0\uB428]") : "";
|
|
789
|
-
const free = !p.needsKey ? chalk11.green(" [\uBB34\uB8CC]") : "";
|
|
790
|
-
console.log(` ${chalk11.cyan(`${String(i + 1).padStart(2)}.`)} ${p.label}${free}${envTag}`);
|
|
791
|
-
console.log(` ${chalk11.gray(p.defaultModel)}`);
|
|
792
|
-
});
|
|
793
|
-
console.log();
|
|
794
|
-
const choice = await ask(chalk11.cyan(" \uBC88\uD638: "));
|
|
795
|
-
const idx = parseInt(choice) - 1;
|
|
796
|
-
if (isNaN(idx) || idx < 0 || idx >= PRESETS.length) {
|
|
797
|
-
console.log(chalk11.red(" \uC798\uBABB\uB41C \uC120\uD0DD.\n"));
|
|
798
|
-
return null;
|
|
799
|
-
}
|
|
800
|
-
const preset = PRESETS[idx];
|
|
801
|
-
console.log(chalk11.green(`
|
|
802
|
-
\u2713 ${preset.label}
|
|
803
|
-
`));
|
|
804
|
-
let apiKey = "";
|
|
805
|
-
if (preset.needsKey) {
|
|
806
|
-
const envKey = detectEnvKey(preset);
|
|
807
|
-
if (envKey) {
|
|
808
|
-
console.log(chalk11.green(` API Key \uC790\uB3D9 \uAC10\uC9C0 (${preset.envKey})`));
|
|
809
|
-
const useEnv = await ask(chalk11.white(` \uC774 \uD0A4\uB97C \uC0AC\uC6A9\uD560\uAE4C\uC694? (Y/n): `));
|
|
810
|
-
if (useEnv.toLowerCase() !== "n") {
|
|
811
|
-
apiKey = envKey;
|
|
812
|
-
}
|
|
813
|
-
}
|
|
814
|
-
if (!apiKey) {
|
|
815
|
-
console.log(chalk11.gray(` \uBC1C\uAE09: ${preset.keyHint}
|
|
816
|
-
`));
|
|
817
|
-
apiKey = await ask(chalk11.white(" API Key: "));
|
|
818
|
-
if (!apiKey) {
|
|
819
|
-
console.log(chalk11.red(" API Key \uD544\uC694.\n"));
|
|
820
|
-
return null;
|
|
821
|
-
}
|
|
822
|
-
}
|
|
823
|
-
}
|
|
824
|
-
let baseUrl = preset.baseUrl;
|
|
825
|
-
if (preset.label === "\uAE30\uD0C0 (OpenAI \uD638\uD658 \uC11C\uBC84)") {
|
|
826
|
-
baseUrl = await ask(chalk11.white(" Base URL: "));
|
|
827
|
-
if (!baseUrl) {
|
|
828
|
-
console.log(chalk11.red(" URL \uD544\uC694.\n"));
|
|
829
|
-
return null;
|
|
830
|
-
}
|
|
831
|
-
}
|
|
832
|
-
let model = preset.defaultModel;
|
|
833
|
-
if (preset.models.length > 0) {
|
|
834
|
-
console.log(chalk11.bold("\n \uBAA8\uB378:\n"));
|
|
835
|
-
const defaultIdx = preset.models.indexOf(preset.defaultModel);
|
|
836
|
-
preset.models.forEach((m, i) => {
|
|
837
|
-
const tag = i === defaultIdx ? chalk11.green(" \u2190 \uCD94\uCC9C") : "";
|
|
838
|
-
console.log(` ${chalk11.cyan(`${String(i + 1).padStart(2)}.`)} ${m}${tag}`);
|
|
839
|
-
});
|
|
840
|
-
console.log(` ${chalk11.cyan(`${String(preset.models.length + 1).padStart(2)}.`)} \uC9C1\uC811 \uC785\uB825`);
|
|
841
|
-
console.log();
|
|
842
|
-
const mc = await ask(chalk11.cyan(` \uBC88\uD638 [${defaultIdx + 1}]: `));
|
|
843
|
-
if (!mc || mc === String(defaultIdx + 1)) {
|
|
844
|
-
model = preset.defaultModel;
|
|
845
|
-
} else {
|
|
846
|
-
const mi = parseInt(mc) - 1;
|
|
847
|
-
if (mi >= 0 && mi < preset.models.length) {
|
|
848
|
-
model = preset.models[mi];
|
|
849
|
-
} else if (parseInt(mc) === preset.models.length + 1) {
|
|
850
|
-
model = await ask(chalk11.white(" \uBAA8\uB378\uBA85: ")) || preset.defaultModel;
|
|
851
|
-
}
|
|
852
|
-
}
|
|
853
|
-
} else if (preset.label === "\uAE30\uD0C0 (OpenAI \uD638\uD658 \uC11C\uBC84)") {
|
|
854
|
-
model = await ask(chalk11.white(` \uBAA8\uB378\uBA85 [${preset.defaultModel}]: `)) || preset.defaultModel;
|
|
855
|
-
}
|
|
856
|
-
console.log(chalk11.green(`
|
|
857
|
-
\u2713 ${preset.label} \xB7 ${model}`));
|
|
858
|
-
console.log(chalk11.gray(" \uC5F0\uACB0 \uD14C\uC2A4\uD2B8 \uC911...\n"));
|
|
859
|
-
const provider = {
|
|
860
|
-
id: preset.label.toLowerCase().replace(/[^a-z0-9]/g, "-").replace(/-+/g, "-"),
|
|
861
|
-
name: preset.label,
|
|
862
|
-
type: preset.type,
|
|
863
|
-
baseUrl,
|
|
864
|
-
apiKey,
|
|
865
|
-
model
|
|
866
|
-
};
|
|
867
|
-
try {
|
|
868
|
-
const client2 = new OpenAI({ apiKey: apiKey || "ollama", baseURL: baseUrl });
|
|
869
|
-
await client2.chat.completions.create({
|
|
870
|
-
model,
|
|
871
|
-
messages: [{ role: "user", content: "Hi" }],
|
|
872
|
-
max_tokens: 5
|
|
873
|
-
});
|
|
874
|
-
console.log(chalk11.green(" \u2713 \uC5F0\uACB0 \uC131\uACF5!\n"));
|
|
875
|
-
} catch (err) {
|
|
876
|
-
console.log(chalk11.yellow(` \u26A0 \uD14C\uC2A4\uD2B8 \uC2E4\uD328: ${err.message}`));
|
|
877
|
-
console.log(chalk11.gray(" \uC124\uC815\uC740 \uC800\uC7A5\uB429\uB2C8\uB2E4.\n"));
|
|
878
|
-
}
|
|
879
|
-
addProvider(provider);
|
|
880
|
-
console.log(chalk11.green.bold(` \u2713 \uC124\uC815 \uC644\uB8CC! ${preset.label} (${model})
|
|
881
|
-
`));
|
|
882
|
-
return provider;
|
|
883
|
-
}
|
|
884
|
-
function registerProviderCommand(program2) {
|
|
885
|
-
const prov = program2.command("provider").description("AI \uD504\uB85C\uBC14\uC774\uB354 \uAD00\uB9AC");
|
|
886
|
-
prov.command("add").description("\uD504\uB85C\uBC14\uC774\uB354 \uCD94\uAC00").action(async () => {
|
|
887
|
-
await guidedProviderSetup();
|
|
562
|
+
console.log(chalk11.green(`
|
|
563
|
+
\u2713 ${preset.label} \xB7 ${model}`));
|
|
564
|
+
console.log(chalk11.gray(" \uC5F0\uACB0 \uD14C\uC2A4\uD2B8 \uC911...\n"));
|
|
565
|
+
const provider = {
|
|
566
|
+
id: preset.label.toLowerCase().replace(/[^a-z0-9]/g, "-").replace(/-+/g, "-"),
|
|
567
|
+
name: preset.label,
|
|
568
|
+
type: preset.type,
|
|
569
|
+
baseUrl,
|
|
570
|
+
apiKey,
|
|
571
|
+
model
|
|
572
|
+
};
|
|
573
|
+
try {
|
|
574
|
+
const client2 = new OpenAI({ apiKey: apiKey || "ollama", baseURL: baseUrl });
|
|
575
|
+
await client2.chat.completions.create({
|
|
576
|
+
model,
|
|
577
|
+
messages: [{ role: "user", content: "Hi" }],
|
|
578
|
+
max_tokens: 5
|
|
579
|
+
});
|
|
580
|
+
console.log(chalk11.green(" \u2713 \uC5F0\uACB0 \uC131\uACF5!\n"));
|
|
581
|
+
} catch (err) {
|
|
582
|
+
console.log(chalk11.yellow(` \u26A0 \uD14C\uC2A4\uD2B8 \uC2E4\uD328: ${err.message}`));
|
|
583
|
+
console.log(chalk11.gray(" \uC124\uC815\uC740 \uC800\uC7A5\uB429\uB2C8\uB2E4.\n"));
|
|
584
|
+
}
|
|
585
|
+
addProvider(provider);
|
|
586
|
+
console.log(chalk11.green.bold(` \u2713 \uC124\uC815 \uC644\uB8CC! ${preset.label} (${model})
|
|
587
|
+
`));
|
|
588
|
+
return provider;
|
|
589
|
+
}
|
|
590
|
+
function registerProviderCommand(program2) {
|
|
591
|
+
const prov = program2.command("provider").description("AI \uD504\uB85C\uBC14\uC774\uB354 \uAD00\uB9AC");
|
|
592
|
+
prov.command("add").description("\uD504\uB85C\uBC14\uC774\uB354 \uCD94\uAC00").action(async () => {
|
|
593
|
+
await guidedProviderSetup();
|
|
888
594
|
});
|
|
889
595
|
prov.command("list").alias("ls").description("\uD504\uB85C\uBC14\uC774\uB354 \uBAA9\uB85D").action(() => {
|
|
890
596
|
const providers = getProviders();
|
|
@@ -1064,1909 +770,1898 @@ var init_provider = __esm({
|
|
|
1064
770
|
needsKey: true,
|
|
1065
771
|
keyHint: "\uC11C\uBC84\uC5D0\uC11C \uBC1C\uAE09\uBC1B\uC740 API Key"
|
|
1066
772
|
}
|
|
1067
|
-
];
|
|
1068
|
-
}
|
|
1069
|
-
});
|
|
1070
|
-
|
|
1071
|
-
// src/agent/llm.ts
|
|
1072
|
-
import OpenAI2 from "openai";
|
|
1073
|
-
function createLLMClient(provider) {
|
|
1074
|
-
const opts = {
|
|
1075
|
-
apiKey: provider.apiKey || "ollama"
|
|
1076
|
-
};
|
|
1077
|
-
if (provider.baseUrl) {
|
|
1078
|
-
opts.baseURL = provider.baseUrl;
|
|
1079
|
-
}
|
|
1080
|
-
return new OpenAI2(opts);
|
|
1081
|
-
}
|
|
1082
|
-
async function streamChat(client2, model, messages, tools2, onDelta) {
|
|
1083
|
-
const params = {
|
|
1084
|
-
model,
|
|
1085
|
-
messages,
|
|
1086
|
-
stream: true
|
|
1087
|
-
};
|
|
1088
|
-
if (tools2 && tools2.length > 0) {
|
|
1089
|
-
params.tools = tools2;
|
|
1090
|
-
}
|
|
1091
|
-
const stream = await client2.chat.completions.create(params);
|
|
1092
|
-
let content = "";
|
|
1093
|
-
const toolCallMap = /* @__PURE__ */ new Map();
|
|
1094
|
-
for await (const chunk of stream) {
|
|
1095
|
-
const delta = chunk.choices[0]?.delta;
|
|
1096
|
-
if (!delta) continue;
|
|
1097
|
-
if (delta.content) {
|
|
1098
|
-
content += delta.content;
|
|
1099
|
-
onDelta?.(delta.content);
|
|
1100
|
-
}
|
|
1101
|
-
if (delta.tool_calls) {
|
|
1102
|
-
for (const tc of delta.tool_calls) {
|
|
1103
|
-
const idx = tc.index;
|
|
1104
|
-
if (!toolCallMap.has(idx)) {
|
|
1105
|
-
toolCallMap.set(idx, { id: tc.id ?? "", name: tc.function?.name ?? "", arguments: "" });
|
|
1106
|
-
}
|
|
1107
|
-
const entry = toolCallMap.get(idx);
|
|
1108
|
-
if (tc.id) entry.id = tc.id;
|
|
1109
|
-
if (tc.function?.name) entry.name = tc.function.name;
|
|
1110
|
-
if (tc.function?.arguments) entry.arguments += tc.function.arguments;
|
|
1111
|
-
}
|
|
1112
|
-
}
|
|
773
|
+
];
|
|
1113
774
|
}
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
775
|
+
});
|
|
776
|
+
|
|
777
|
+
// src/api/document.ts
|
|
778
|
+
var document_exports = {};
|
|
779
|
+
__export(document_exports, {
|
|
780
|
+
getDocumentInfo: () => getDocumentInfo,
|
|
781
|
+
listDocuments: () => listDocuments,
|
|
782
|
+
uploadDocument: () => uploadDocument
|
|
783
|
+
});
|
|
784
|
+
import { createReadStream, statSync } from "fs";
|
|
785
|
+
import { basename } from "path";
|
|
786
|
+
async function listDocuments(collectionId) {
|
|
787
|
+
const client2 = getClient();
|
|
788
|
+
const params = {};
|
|
789
|
+
if (collectionId) params.collection_id = collectionId;
|
|
790
|
+
const res = await client2.get("/api/documents/list", { params });
|
|
791
|
+
return res.data.documents ?? res.data ?? [];
|
|
792
|
+
}
|
|
793
|
+
async function uploadDocument(filePath, collectionId, name) {
|
|
794
|
+
const client2 = getClient();
|
|
795
|
+
const stat = statSync(filePath);
|
|
796
|
+
const fileName = name || basename(filePath);
|
|
797
|
+
const FormData = (await import("buffer")).Blob ? globalThis.FormData : null;
|
|
798
|
+
if (!FormData) throw new Error("FormData not available");
|
|
799
|
+
const form = new FormData();
|
|
800
|
+
const fileBlob = new Blob([createReadStream(filePath)]);
|
|
801
|
+
form.append("file", fileBlob, fileName);
|
|
802
|
+
if (collectionId) form.append("collection_id", collectionId);
|
|
803
|
+
const res = await client2.post("/api/documents/upload", form, {
|
|
804
|
+
headers: { "Content-Type": "multipart/form-data" },
|
|
805
|
+
maxBodyLength: stat.size + 1024 * 1024
|
|
806
|
+
});
|
|
807
|
+
return res.data;
|
|
808
|
+
}
|
|
809
|
+
async function getDocumentInfo(docId) {
|
|
810
|
+
const client2 = getClient();
|
|
811
|
+
const res = await client2.get(`/api/documents/${docId}`);
|
|
812
|
+
return res.data;
|
|
1118
813
|
}
|
|
1119
|
-
var
|
|
1120
|
-
"src/
|
|
814
|
+
var init_document = __esm({
|
|
815
|
+
"src/api/document.ts"() {
|
|
1121
816
|
"use strict";
|
|
817
|
+
init_client();
|
|
1122
818
|
}
|
|
1123
819
|
});
|
|
1124
820
|
|
|
1125
|
-
// src/
|
|
1126
|
-
var
|
|
1127
|
-
__export(
|
|
1128
|
-
|
|
1129
|
-
|
|
821
|
+
// src/api/ontology.ts
|
|
822
|
+
var ontology_exports = {};
|
|
823
|
+
__export(ontology_exports, {
|
|
824
|
+
getGraphStats: () => getGraphStats,
|
|
825
|
+
listGraphs: () => listGraphs,
|
|
826
|
+
queryGraphRAG: () => queryGraphRAG,
|
|
827
|
+
queryGraphRAGMultiTurn: () => queryGraphRAGMultiTurn
|
|
1130
828
|
});
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
const
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
829
|
+
async function queryGraphRAG(query, graphId, opts) {
|
|
830
|
+
const client2 = getClient();
|
|
831
|
+
const res = await client2.post("/api/graph-rag", {
|
|
832
|
+
query,
|
|
833
|
+
graph_id: graphId,
|
|
834
|
+
use_scs: opts?.scs ?? true
|
|
835
|
+
});
|
|
836
|
+
return res.data;
|
|
837
|
+
}
|
|
838
|
+
async function queryGraphRAGMultiTurn(query, sessionId, graphId, opts) {
|
|
839
|
+
const client2 = getClient();
|
|
840
|
+
const res = await client2.post("/api/graph-rag/multi-turn", {
|
|
841
|
+
query,
|
|
842
|
+
session_id: sessionId,
|
|
843
|
+
graph_id: graphId,
|
|
844
|
+
max_turns: opts?.maxTurns ?? 5
|
|
845
|
+
});
|
|
846
|
+
return res.data;
|
|
847
|
+
}
|
|
848
|
+
async function getGraphStats(graphId) {
|
|
849
|
+
const client2 = getClient();
|
|
850
|
+
const res = await client2.get(`/api/graph/${graphId}/stats`);
|
|
851
|
+
return res.data;
|
|
852
|
+
}
|
|
853
|
+
async function listGraphs() {
|
|
854
|
+
const client2 = getClient();
|
|
855
|
+
const res = await client2.get("/api/graph/list");
|
|
856
|
+
return res.data.graphs ?? res.data ?? [];
|
|
1144
857
|
}
|
|
1145
|
-
var
|
|
1146
|
-
|
|
1147
|
-
"src/agent/tools/file-read.ts"() {
|
|
858
|
+
var init_ontology = __esm({
|
|
859
|
+
"src/api/ontology.ts"() {
|
|
1148
860
|
"use strict";
|
|
1149
|
-
|
|
1150
|
-
type: "function",
|
|
1151
|
-
function: {
|
|
1152
|
-
name: "file_read",
|
|
1153
|
-
description: "\uD30C\uC77C \uB0B4\uC6A9\uC744 \uC77D\uC2B5\uB2C8\uB2E4. \uC904 \uBC88\uD638\uAC00 \uD3EC\uD568\uB429\uB2C8\uB2E4.",
|
|
1154
|
-
parameters: {
|
|
1155
|
-
type: "object",
|
|
1156
|
-
properties: {
|
|
1157
|
-
path: { type: "string", description: "\uD30C\uC77C \uACBD\uB85C" },
|
|
1158
|
-
start_line: { type: "number", description: "\uC2DC\uC791 \uC904 \uBC88\uD638 (\uC120\uD0DD)" },
|
|
1159
|
-
end_line: { type: "number", description: "\uB05D \uC904 \uBC88\uD638 (\uC120\uD0DD)" }
|
|
1160
|
-
},
|
|
1161
|
-
required: ["path"]
|
|
1162
|
-
}
|
|
1163
|
-
}
|
|
1164
|
-
};
|
|
861
|
+
init_client();
|
|
1165
862
|
}
|
|
1166
863
|
});
|
|
1167
864
|
|
|
1168
|
-
// src/
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
const
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
865
|
+
// src/index.ts
|
|
866
|
+
import { Command } from "commander";
|
|
867
|
+
import chalk15 from "chalk";
|
|
868
|
+
|
|
869
|
+
// src/commands/config.ts
|
|
870
|
+
init_store();
|
|
871
|
+
init_client();
|
|
872
|
+
init_format();
|
|
873
|
+
import chalk2 from "chalk";
|
|
874
|
+
function registerConfigCommand(program2) {
|
|
875
|
+
const config = program2.command("config").description("XGEN CLI \uC124\uC815 \uAD00\uB9AC");
|
|
876
|
+
config.command("set-server <url>").description("XGEN \uC11C\uBC84 URL \uC124\uC815").action((url) => {
|
|
877
|
+
if (!url.startsWith("http://") && !url.startsWith("https://")) {
|
|
878
|
+
printError("URL\uC740 http:// \uB610\uB294 https://\uB85C \uC2DC\uC791\uD574\uC57C \uD569\uB2C8\uB2E4");
|
|
879
|
+
process.exit(1);
|
|
880
|
+
}
|
|
881
|
+
setServer(url);
|
|
882
|
+
resetClient();
|
|
883
|
+
printSuccess(`\uC11C\uBC84 \uC124\uC815 \uC644\uB8CC: ${chalk2.underline(url)}`);
|
|
884
|
+
});
|
|
885
|
+
config.command("get-server").description("\uD604\uC7AC \uC124\uC815\uB41C \uC11C\uBC84 URL \uD655\uC778").action(() => {
|
|
886
|
+
const server = getServer();
|
|
887
|
+
if (server) {
|
|
888
|
+
console.log(server);
|
|
889
|
+
} else {
|
|
890
|
+
printError("\uC11C\uBC84\uAC00 \uC124\uC815\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4");
|
|
891
|
+
console.log(" \uC124\uC815: xgen config set-server <url>");
|
|
892
|
+
}
|
|
893
|
+
});
|
|
894
|
+
config.command("list").description("\uC804\uCCB4 \uC124\uC815 \uD655\uC778").action(() => {
|
|
895
|
+
const cfg = getConfig();
|
|
896
|
+
console.log(chalk2.bold("\nXGEN CLI \uC124\uC815"));
|
|
897
|
+
console.log(chalk2.gray("\u2500".repeat(40)));
|
|
898
|
+
printKeyValue("\uC11C\uBC84", cfg.server);
|
|
899
|
+
printKeyValue("\uAE30\uBCF8 \uC6CC\uD06C\uD50C\uB85C\uC6B0", cfg.defaultWorkflow);
|
|
900
|
+
printKeyValue("\uD14C\uB9C8", cfg.theme);
|
|
901
|
+
printKeyValue("\uC2A4\uD2B8\uB9BC \uB85C\uADF8", String(cfg.streamLogs));
|
|
902
|
+
console.log();
|
|
903
|
+
});
|
|
904
|
+
config.command("set <key> <value>").description("\uC124\uC815 \uAC12 \uBCC0\uACBD").action((key, value) => {
|
|
905
|
+
const allowedKeys = ["defaultWorkflow", "theme", "streamLogs"];
|
|
906
|
+
if (!allowedKeys.includes(key)) {
|
|
907
|
+
printError(`\uC54C \uC218 \uC5C6\uB294 \uC124\uC815 \uD0A4: ${key}`);
|
|
908
|
+
console.log(` \uC0AC\uC6A9 \uAC00\uB2A5: ${allowedKeys.join(", ")}`);
|
|
909
|
+
process.exit(1);
|
|
910
|
+
}
|
|
911
|
+
const parsed = key === "streamLogs" ? value === "true" : value;
|
|
912
|
+
setConfig({ [key]: parsed });
|
|
913
|
+
printSuccess(`${key} = ${value}`);
|
|
914
|
+
});
|
|
1186
915
|
}
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
916
|
+
|
|
917
|
+
// src/commands/login.ts
|
|
918
|
+
init_auth();
|
|
919
|
+
init_store();
|
|
920
|
+
init_format();
|
|
921
|
+
import chalk3 from "chalk";
|
|
922
|
+
import { createInterface } from "readline";
|
|
923
|
+
function prompt(question, hidden = false) {
|
|
924
|
+
return new Promise((resolve) => {
|
|
925
|
+
const rl = createInterface({
|
|
926
|
+
input: process.stdin,
|
|
927
|
+
output: process.stdout
|
|
928
|
+
});
|
|
929
|
+
if (hidden) {
|
|
930
|
+
process.stdout.write(question);
|
|
931
|
+
const stdin = process.stdin;
|
|
932
|
+
const wasRaw = stdin.isRaw;
|
|
933
|
+
if (stdin.isTTY) stdin.setRawMode(true);
|
|
934
|
+
let password = "";
|
|
935
|
+
const onData = (ch) => {
|
|
936
|
+
const c = ch.toString("utf8");
|
|
937
|
+
if (c === "\n" || c === "\r" || c === "") {
|
|
938
|
+
if (stdin.isTTY) stdin.setRawMode(wasRaw ?? false);
|
|
939
|
+
stdin.removeListener("data", onData);
|
|
940
|
+
process.stdout.write("\n");
|
|
941
|
+
rl.close();
|
|
942
|
+
resolve(password);
|
|
943
|
+
} else if (c === "") {
|
|
944
|
+
process.exit(0);
|
|
945
|
+
} else if (c === "\x7F" || c === "\b") {
|
|
946
|
+
if (password.length > 0) {
|
|
947
|
+
password = password.slice(0, -1);
|
|
948
|
+
process.stdout.write("\b \b");
|
|
949
|
+
}
|
|
950
|
+
} else {
|
|
951
|
+
password += c;
|
|
952
|
+
process.stdout.write("*");
|
|
1203
953
|
}
|
|
954
|
+
};
|
|
955
|
+
stdin.on("data", onData);
|
|
956
|
+
} else {
|
|
957
|
+
rl.question(question, (answer) => {
|
|
958
|
+
rl.close();
|
|
959
|
+
resolve(answer.trim());
|
|
960
|
+
});
|
|
961
|
+
}
|
|
962
|
+
});
|
|
963
|
+
}
|
|
964
|
+
function registerLoginCommand(program2) {
|
|
965
|
+
program2.command("login").description("XGEN \uC11C\uBC84\uC5D0 \uB85C\uADF8\uC778").option("-e, --email <email>", "\uC774\uBA54\uC77C").option("-p, --password <password>", "\uBE44\uBC00\uBC88\uD638").action(async (opts) => {
|
|
966
|
+
const server = requireServer();
|
|
967
|
+
printHeader("XGEN Login");
|
|
968
|
+
console.log(chalk3.gray(`\uC11C\uBC84: ${server}
|
|
969
|
+
`));
|
|
970
|
+
let email = opts.email;
|
|
971
|
+
let password = opts.password;
|
|
972
|
+
if (!email) {
|
|
973
|
+
email = await prompt(chalk3.white("\uC774\uBA54\uC77C: "));
|
|
974
|
+
}
|
|
975
|
+
if (!password) {
|
|
976
|
+
password = await prompt(chalk3.white("\uBE44\uBC00\uBC88\uD638: "), true);
|
|
977
|
+
}
|
|
978
|
+
if (!email || !password) {
|
|
979
|
+
printError("\uC774\uBA54\uC77C\uACFC \uBE44\uBC00\uBC88\uD638\uB97C \uBAA8\uB450 \uC785\uB825\uD558\uC138\uC694");
|
|
980
|
+
process.exit(1);
|
|
981
|
+
}
|
|
982
|
+
try {
|
|
983
|
+
const result = await apiLogin(email, password);
|
|
984
|
+
if (result.success && result.access_token) {
|
|
985
|
+
setAuth({
|
|
986
|
+
accessToken: result.access_token,
|
|
987
|
+
refreshToken: result.refresh_token ?? "",
|
|
988
|
+
userId: result.user_id ?? "",
|
|
989
|
+
username: result.username ?? "",
|
|
990
|
+
isAdmin: false,
|
|
991
|
+
expiresAt: null
|
|
992
|
+
});
|
|
993
|
+
console.log();
|
|
994
|
+
printSuccess(`\uB85C\uADF8\uC778 \uC131\uACF5! ${chalk3.bold(result.username ?? email)}`);
|
|
995
|
+
} else {
|
|
996
|
+
printError(result.message || "\uB85C\uADF8\uC778 \uC2E4\uD328");
|
|
997
|
+
process.exit(1);
|
|
1204
998
|
}
|
|
1205
|
-
}
|
|
1206
|
-
|
|
1207
|
-
});
|
|
1208
|
-
|
|
1209
|
-
// src/agent/tools/file-edit.ts
|
|
1210
|
-
var file_edit_exports = {};
|
|
1211
|
-
__export(file_edit_exports, {
|
|
1212
|
-
definition: () => definition3,
|
|
1213
|
-
execute: () => execute3
|
|
1214
|
-
});
|
|
1215
|
-
import { readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
|
|
1216
|
-
async function execute3(args) {
|
|
1217
|
-
const path = args.path;
|
|
1218
|
-
const oldText = args.old_text;
|
|
1219
|
-
const newText = args.new_text;
|
|
1220
|
-
try {
|
|
1221
|
-
const content = readFileSync3(path, "utf-8");
|
|
1222
|
-
if (!content.includes(oldText)) {
|
|
1223
|
-
return `Error: \uD14D\uC2A4\uD2B8\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4`;
|
|
999
|
+
} catch (err) {
|
|
1000
|
+
const msg = err?.response?.data?.message ?? err?.response?.data?.detail ?? err.message;
|
|
1001
|
+
printError(`\uB85C\uADF8\uC778 \uC2E4\uD328: ${msg}`);
|
|
1002
|
+
process.exit(1);
|
|
1224
1003
|
}
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
}
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1004
|
+
});
|
|
1005
|
+
program2.command("logout").description("\uB85C\uADF8\uC544\uC6C3").action(async () => {
|
|
1006
|
+
const { clearAuth: clearAuth2 } = await Promise.resolve().then(() => (init_store(), store_exports));
|
|
1007
|
+
clearAuth2();
|
|
1008
|
+
printSuccess("\uB85C\uADF8\uC544\uC6C3 \uC644\uB8CC");
|
|
1009
|
+
});
|
|
1010
|
+
program2.command("whoami").description("\uD604\uC7AC \uB85C\uADF8\uC778\uB41C \uC0AC\uC6A9\uC790 \uC815\uBCF4").action(async () => {
|
|
1011
|
+
const auth = getAuth();
|
|
1012
|
+
if (!auth) {
|
|
1013
|
+
printError("\uB85C\uADF8\uC778\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. xgen login \uC2E4\uD589\uD558\uC138\uC694");
|
|
1014
|
+
process.exit(1);
|
|
1015
|
+
}
|
|
1016
|
+
const server = requireServer();
|
|
1017
|
+
console.log(chalk3.bold("\n\uD604\uC7AC \uC0AC\uC6A9\uC790"));
|
|
1018
|
+
console.log(chalk3.gray("\u2500".repeat(30)));
|
|
1019
|
+
console.log(` ${chalk3.gray("\uC11C\uBC84:")} ${server}`);
|
|
1020
|
+
console.log(` ${chalk3.gray("\uC0AC\uC6A9\uC790:")} ${chalk3.bold(auth.username)}`);
|
|
1021
|
+
console.log(` ${chalk3.gray("User ID:")} ${auth.userId}`);
|
|
1022
|
+
try {
|
|
1023
|
+
const { apiValidate: apiValidate2 } = await Promise.resolve().then(() => (init_auth(), auth_exports));
|
|
1024
|
+
const result = await apiValidate2(auth.accessToken);
|
|
1025
|
+
if (result.valid) {
|
|
1026
|
+
console.log(` ${chalk3.gray("\uC0C1\uD0DC:")} ${chalk3.green("\uD65C\uC131")}`);
|
|
1027
|
+
if (result.is_admin) {
|
|
1028
|
+
console.log(` ${chalk3.gray("\uAD8C\uD55C:")} ${chalk3.yellow("\uAD00\uB9AC\uC790")}`);
|
|
1249
1029
|
}
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
}
|
|
1253
|
-
});
|
|
1254
|
-
|
|
1255
|
-
// src/agent/tools/bash.ts
|
|
1256
|
-
var bash_exports = {};
|
|
1257
|
-
__export(bash_exports, {
|
|
1258
|
-
definition: () => definition4,
|
|
1259
|
-
execute: () => execute4
|
|
1260
|
-
});
|
|
1261
|
-
import { execSync } from "child_process";
|
|
1262
|
-
async function execute4(args) {
|
|
1263
|
-
const command = args.command;
|
|
1264
|
-
try {
|
|
1265
|
-
const output = execSync(command, {
|
|
1266
|
-
encoding: "utf-8",
|
|
1267
|
-
timeout: 3e4,
|
|
1268
|
-
maxBuffer: 1024 * 1024,
|
|
1269
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
1270
|
-
});
|
|
1271
|
-
return output || "(no output)";
|
|
1272
|
-
} catch (err) {
|
|
1273
|
-
const e = err;
|
|
1274
|
-
return (e.stdout || "") + (e.stderr || "") || `Error: ${e.message}`;
|
|
1275
|
-
}
|
|
1276
|
-
}
|
|
1277
|
-
var definition4;
|
|
1278
|
-
var init_bash = __esm({
|
|
1279
|
-
"src/agent/tools/bash.ts"() {
|
|
1280
|
-
"use strict";
|
|
1281
|
-
definition4 = {
|
|
1282
|
-
type: "function",
|
|
1283
|
-
function: {
|
|
1284
|
-
name: "bash",
|
|
1285
|
-
description: "\uC178 \uBA85\uB839\uC5B4\uB97C \uC2E4\uD589\uD569\uB2C8\uB2E4. stdout + stderr\uB97C \uBC18\uD658\uD569\uB2C8\uB2E4.",
|
|
1286
|
-
parameters: {
|
|
1287
|
-
type: "object",
|
|
1288
|
-
properties: {
|
|
1289
|
-
command: { type: "string", description: "\uC2E4\uD589\uD560 \uBA85\uB839\uC5B4" }
|
|
1290
|
-
},
|
|
1291
|
-
required: ["command"]
|
|
1030
|
+
if (result.user_type) {
|
|
1031
|
+
console.log(` ${chalk3.gray("\uC720\uD615:")} ${result.user_type}`);
|
|
1292
1032
|
}
|
|
1033
|
+
} else {
|
|
1034
|
+
console.log(` ${chalk3.gray("\uC0C1\uD0DC:")} ${chalk3.red("\uD1A0\uD070 \uB9CC\uB8CC")}`);
|
|
1293
1035
|
}
|
|
1294
|
-
}
|
|
1295
|
-
}
|
|
1296
|
-
}
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
var grep_exports = {};
|
|
1300
|
-
__export(grep_exports, {
|
|
1301
|
-
definition: () => definition5,
|
|
1302
|
-
execute: () => execute5
|
|
1303
|
-
});
|
|
1304
|
-
import { execSync as execSync2 } from "child_process";
|
|
1305
|
-
async function execute5(args) {
|
|
1306
|
-
const pattern = args.pattern;
|
|
1307
|
-
const path = args.path || ".";
|
|
1308
|
-
const glob = args.glob;
|
|
1309
|
-
try {
|
|
1310
|
-
let cmd = `grep -rn --color=never "${pattern.replace(/"/g, '\\"')}" "${path}"`;
|
|
1311
|
-
if (glob) cmd += ` --include="${glob}"`;
|
|
1312
|
-
cmd += " | head -50";
|
|
1313
|
-
const output = execSync2(cmd, {
|
|
1314
|
-
encoding: "utf-8",
|
|
1315
|
-
timeout: 1e4,
|
|
1316
|
-
maxBuffer: 512 * 1024,
|
|
1317
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
1318
|
-
});
|
|
1319
|
-
return output || "\uC77C\uCE58\uD558\uB294 \uACB0\uACFC \uC5C6\uC74C";
|
|
1320
|
-
} catch {
|
|
1321
|
-
return "\uC77C\uCE58\uD558\uB294 \uACB0\uACFC \uC5C6\uC74C";
|
|
1322
|
-
}
|
|
1036
|
+
} catch {
|
|
1037
|
+
console.log(` ${chalk3.gray("\uC0C1\uD0DC:")} ${chalk3.yellow("\uAC80\uC99D \uBD88\uAC00 (\uC11C\uBC84 \uC5F0\uACB0 \uC2E4\uD328)")}`);
|
|
1038
|
+
}
|
|
1039
|
+
console.log();
|
|
1040
|
+
});
|
|
1323
1041
|
}
|
|
1324
|
-
var definition5;
|
|
1325
|
-
var init_grep = __esm({
|
|
1326
|
-
"src/agent/tools/grep.ts"() {
|
|
1327
|
-
"use strict";
|
|
1328
|
-
definition5 = {
|
|
1329
|
-
type: "function",
|
|
1330
|
-
function: {
|
|
1331
|
-
name: "grep",
|
|
1332
|
-
description: "\uD30C\uC77C\uC5D0\uC11C \uD328\uD134\uC744 \uAC80\uC0C9\uD569\uB2C8\uB2E4 (\uC7AC\uADC0, \uC904 \uBC88\uD638 \uD3EC\uD568).",
|
|
1333
|
-
parameters: {
|
|
1334
|
-
type: "object",
|
|
1335
|
-
properties: {
|
|
1336
|
-
pattern: { type: "string", description: "\uAC80\uC0C9 \uD328\uD134 (\uC815\uADDC\uC2DD)" },
|
|
1337
|
-
path: { type: "string", description: "\uAC80\uC0C9 \uB514\uB809\uD1A0\uB9AC \uB610\uB294 \uD30C\uC77C (\uAE30\uBCF8: .)" },
|
|
1338
|
-
glob: { type: "string", description: "\uD30C\uC77C \uD544\uD130 (\uC608: *.ts)" }
|
|
1339
|
-
},
|
|
1340
|
-
required: ["pattern"]
|
|
1341
|
-
}
|
|
1342
|
-
}
|
|
1343
|
-
};
|
|
1344
|
-
}
|
|
1345
|
-
});
|
|
1346
1042
|
|
|
1347
|
-
// src/
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
async function execute6(args) {
|
|
1355
|
-
const path = args.path || ".";
|
|
1356
|
-
const pattern = args.pattern;
|
|
1043
|
+
// src/commands/workflow/list.ts
|
|
1044
|
+
init_store();
|
|
1045
|
+
init_workflow();
|
|
1046
|
+
init_format();
|
|
1047
|
+
import chalk4 from "chalk";
|
|
1048
|
+
async function workflowList(opts) {
|
|
1049
|
+
requireAuth();
|
|
1357
1050
|
try {
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1051
|
+
if (opts.detail) {
|
|
1052
|
+
const workflows = await getWorkflowListDetail();
|
|
1053
|
+
if (!workflows || workflows.length === 0) {
|
|
1054
|
+
console.log(chalk4.yellow("\n\uC6CC\uD06C\uD50C\uB85C\uC6B0\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.\n"));
|
|
1055
|
+
return;
|
|
1056
|
+
}
|
|
1057
|
+
printHeader(`\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uBAA9\uB85D (${workflows.length}\uAC1C)`);
|
|
1058
|
+
console.log();
|
|
1059
|
+
printTable(
|
|
1060
|
+
["#", "ID", "\uC774\uB984", "\uBC30\uD3EC", "\uC5C5\uB370\uC774\uD2B8"],
|
|
1061
|
+
workflows.map((w, i) => [
|
|
1062
|
+
String(i + 1),
|
|
1063
|
+
(w.workflow_id ?? w.id ?? "-").slice(0, 12),
|
|
1064
|
+
truncate(w.workflow_name ?? "-", 30),
|
|
1065
|
+
w.is_deployed ? chalk4.green("\uBC30\uD3EC\uB428") : chalk4.gray("\uBBF8\uBC30\uD3EC"),
|
|
1066
|
+
formatDate(w.updated_at)
|
|
1067
|
+
])
|
|
1068
|
+
);
|
|
1361
1069
|
} else {
|
|
1362
|
-
|
|
1070
|
+
const workflows = await listWorkflows();
|
|
1071
|
+
if (!workflows || workflows.length === 0) {
|
|
1072
|
+
console.log(chalk4.yellow("\n\uC6CC\uD06C\uD50C\uB85C\uC6B0\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.\n"));
|
|
1073
|
+
return;
|
|
1074
|
+
}
|
|
1075
|
+
printHeader(`\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uBAA9\uB85D (${workflows.length}\uAC1C)`);
|
|
1076
|
+
console.log();
|
|
1077
|
+
printTable(
|
|
1078
|
+
["#", "ID", "\uC774\uB984"],
|
|
1079
|
+
workflows.map((w, i) => [
|
|
1080
|
+
String(i + 1),
|
|
1081
|
+
(w.workflow_id ?? w.id ?? "-").slice(0, 12),
|
|
1082
|
+
w.workflow_name ?? "-"
|
|
1083
|
+
])
|
|
1084
|
+
);
|
|
1363
1085
|
}
|
|
1364
|
-
|
|
1365
|
-
encoding: "utf-8",
|
|
1366
|
-
timeout: 1e4,
|
|
1367
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
1368
|
-
});
|
|
1369
|
-
return output || "(empty)";
|
|
1086
|
+
console.log();
|
|
1370
1087
|
} catch (err) {
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
var definition6;
|
|
1375
|
-
var init_list_files = __esm({
|
|
1376
|
-
"src/agent/tools/list-files.ts"() {
|
|
1377
|
-
"use strict";
|
|
1378
|
-
definition6 = {
|
|
1379
|
-
type: "function",
|
|
1380
|
-
function: {
|
|
1381
|
-
name: "list_files",
|
|
1382
|
-
description: "\uB514\uB809\uD1A0\uB9AC\uC758 \uD30C\uC77C/\uD3F4\uB354 \uBAA9\uB85D\uC744 \uBC18\uD658\uD569\uB2C8\uB2E4. glob \uD328\uD134 \uC9C0\uC6D0.",
|
|
1383
|
-
parameters: {
|
|
1384
|
-
type: "object",
|
|
1385
|
-
properties: {
|
|
1386
|
-
path: { type: "string", description: "\uB514\uB809\uD1A0\uB9AC \uACBD\uB85C (\uAE30\uBCF8: .)" },
|
|
1387
|
-
pattern: { type: "string", description: "glob \uD328\uD134 (\uC608: **/*.ts)" }
|
|
1388
|
-
}
|
|
1389
|
-
}
|
|
1390
|
-
}
|
|
1391
|
-
};
|
|
1392
|
-
}
|
|
1393
|
-
});
|
|
1394
|
-
|
|
1395
|
-
// src/agent/tools/sandbox.ts
|
|
1396
|
-
var sandbox_exports = {};
|
|
1397
|
-
__export(sandbox_exports, {
|
|
1398
|
-
definition: () => definition7,
|
|
1399
|
-
execute: () => execute7
|
|
1400
|
-
});
|
|
1401
|
-
import { execSync as execSync4 } from "child_process";
|
|
1402
|
-
import { mkdirSync as mkdirSync3, writeFileSync as writeFileSync4, existsSync as existsSync2, rmSync } from "fs";
|
|
1403
|
-
import { join as join2 } from "path";
|
|
1404
|
-
import { tmpdir } from "os";
|
|
1405
|
-
function ensureSandbox() {
|
|
1406
|
-
if (!existsSync2(SANDBOX_DIR)) {
|
|
1407
|
-
mkdirSync3(SANDBOX_DIR, { recursive: true });
|
|
1088
|
+
const msg = err.message;
|
|
1089
|
+
printError(`\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uBAA9\uB85D \uC870\uD68C \uC2E4\uD328: ${msg}`);
|
|
1090
|
+
process.exit(1);
|
|
1408
1091
|
}
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
execSync4(`npm install ${pkgList}`, {
|
|
1433
|
-
cwd: runDir,
|
|
1434
|
-
encoding: "utf-8",
|
|
1435
|
-
timeout: 6e4,
|
|
1436
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
1437
|
-
});
|
|
1092
|
+
}
|
|
1093
|
+
|
|
1094
|
+
// src/commands/workflow/info.ts
|
|
1095
|
+
init_store();
|
|
1096
|
+
init_workflow();
|
|
1097
|
+
init_format();
|
|
1098
|
+
import chalk5 from "chalk";
|
|
1099
|
+
async function workflowInfo(workflowId) {
|
|
1100
|
+
requireAuth();
|
|
1101
|
+
try {
|
|
1102
|
+
const detail = await getWorkflowDetail(workflowId);
|
|
1103
|
+
printHeader(`\uC6CC\uD06C\uD50C\uB85C\uC6B0: ${detail.workflow_name ?? workflowId}`);
|
|
1104
|
+
console.log();
|
|
1105
|
+
printKeyValue("ID", detail.id);
|
|
1106
|
+
printKeyValue("\uC774\uB984", detail.workflow_name);
|
|
1107
|
+
printKeyValue("\uC124\uBA85", detail.description ?? "(\uC5C6\uC74C)");
|
|
1108
|
+
if (detail.nodes && Array.isArray(detail.nodes)) {
|
|
1109
|
+
console.log();
|
|
1110
|
+
console.log(chalk5.bold(" \uB178\uB4DC \uAD6C\uC131:"));
|
|
1111
|
+
for (const node of detail.nodes) {
|
|
1112
|
+
const label = node.data?.label ?? node.id;
|
|
1113
|
+
const type = node.data?.type ?? "unknown";
|
|
1114
|
+
console.log(` ${chalk5.cyan("\u2022")} ${label} ${chalk5.gray(`(${type})`)}`);
|
|
1438
1115
|
}
|
|
1439
1116
|
}
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
} else if (language === "typescript") {
|
|
1447
|
-
filename = "script.ts";
|
|
1448
|
-
writeFileSync4(join2(runDir, filename), code, "utf-8");
|
|
1449
|
-
cmd = `npx tsx ${filename}`;
|
|
1450
|
-
} else {
|
|
1451
|
-
filename = "script.mjs";
|
|
1452
|
-
writeFileSync4(join2(runDir, filename), code, "utf-8");
|
|
1453
|
-
cmd = `node ${filename}`;
|
|
1117
|
+
if (detail.parameters && Object.keys(detail.parameters).length > 0) {
|
|
1118
|
+
console.log();
|
|
1119
|
+
console.log(chalk5.bold(" \uD30C\uB77C\uBBF8\uD130:"));
|
|
1120
|
+
for (const [key, val] of Object.entries(detail.parameters)) {
|
|
1121
|
+
console.log(` ${chalk5.gray(key)}: ${JSON.stringify(val)}`);
|
|
1122
|
+
}
|
|
1454
1123
|
}
|
|
1455
|
-
|
|
1456
|
-
cwd: runDir,
|
|
1457
|
-
encoding: "utf-8",
|
|
1458
|
-
timeout: 3e4,
|
|
1459
|
-
maxBuffer: 1024 * 1024,
|
|
1460
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
1461
|
-
});
|
|
1462
|
-
return output || "(no output)";
|
|
1124
|
+
console.log();
|
|
1463
1125
|
} catch (err) {
|
|
1464
|
-
const
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
try {
|
|
1468
|
-
rmSync(runDir, { recursive: true, force: true });
|
|
1469
|
-
} catch {
|
|
1470
|
-
}
|
|
1126
|
+
const msg = err.message;
|
|
1127
|
+
printError(`\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uC870\uD68C \uC2E4\uD328: ${msg}`);
|
|
1128
|
+
process.exit(1);
|
|
1471
1129
|
}
|
|
1472
1130
|
}
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1131
|
+
|
|
1132
|
+
// src/commands/workflow/run.ts
|
|
1133
|
+
init_store();
|
|
1134
|
+
init_workflow();
|
|
1135
|
+
import chalk7 from "chalk";
|
|
1136
|
+
import { randomUUID } from "crypto";
|
|
1137
|
+
|
|
1138
|
+
// src/utils/sse.ts
|
|
1139
|
+
async function parseSSEStream(stream, onEvent, onDone, onError) {
|
|
1140
|
+
let buffer = "";
|
|
1141
|
+
return new Promise((resolve, reject) => {
|
|
1142
|
+
stream.on("data", (chunk) => {
|
|
1143
|
+
buffer += chunk.toString();
|
|
1144
|
+
const parts = buffer.split("\n\n");
|
|
1145
|
+
buffer = parts.pop() ?? "";
|
|
1146
|
+
for (const part of parts) {
|
|
1147
|
+
const lines = part.split("\n");
|
|
1148
|
+
let data = "";
|
|
1149
|
+
for (const line of lines) {
|
|
1150
|
+
if (line.startsWith("data: ")) {
|
|
1151
|
+
data += line.slice(6);
|
|
1152
|
+
} else if (line.startsWith("data:")) {
|
|
1153
|
+
data += line.slice(5);
|
|
1154
|
+
}
|
|
1155
|
+
}
|
|
1156
|
+
if (!data) continue;
|
|
1157
|
+
try {
|
|
1158
|
+
const event = JSON.parse(data);
|
|
1159
|
+
onEvent(event);
|
|
1160
|
+
} catch {
|
|
1161
|
+
onEvent({ type: "token", content: data });
|
|
1162
|
+
}
|
|
1163
|
+
}
|
|
1164
|
+
});
|
|
1165
|
+
stream.on("end", () => {
|
|
1166
|
+
if (buffer.trim()) {
|
|
1167
|
+
const lines = buffer.split("\n");
|
|
1168
|
+
for (const line of lines) {
|
|
1169
|
+
if (line.startsWith("data: ")) {
|
|
1170
|
+
try {
|
|
1171
|
+
const event = JSON.parse(line.slice(6));
|
|
1172
|
+
onEvent(event);
|
|
1173
|
+
} catch {
|
|
1174
|
+
onEvent({ type: "token", content: line.slice(6) });
|
|
1496
1175
|
}
|
|
1497
|
-
}
|
|
1498
|
-
required: ["language", "code"]
|
|
1176
|
+
}
|
|
1499
1177
|
}
|
|
1500
1178
|
}
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
});
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
}
|
|
1509
|
-
async function executeTool(name, args) {
|
|
1510
|
-
const tool = toolMap.get(name);
|
|
1511
|
-
if (!tool) return `Unknown tool: ${name}`;
|
|
1512
|
-
return tool.execute(args);
|
|
1179
|
+
onDone?.();
|
|
1180
|
+
resolve();
|
|
1181
|
+
});
|
|
1182
|
+
stream.on("error", (err) => {
|
|
1183
|
+
onError?.(err);
|
|
1184
|
+
reject(err);
|
|
1185
|
+
});
|
|
1186
|
+
});
|
|
1513
1187
|
}
|
|
1514
|
-
|
|
1515
|
-
|
|
1188
|
+
|
|
1189
|
+
// src/commands/workflow/run.ts
|
|
1190
|
+
init_format();
|
|
1191
|
+
|
|
1192
|
+
// src/utils/markdown.ts
|
|
1193
|
+
import chalk6 from "chalk";
|
|
1194
|
+
var CODE_BLOCK_RE = /```(\w*)\n([\s\S]*?)```/g;
|
|
1195
|
+
var INLINE_CODE_RE = /`([^`]+)`/g;
|
|
1196
|
+
var BOLD_RE = /\*\*(.+?)\*\*/g;
|
|
1197
|
+
var HEADING_RE = /^(#{1,3})\s+(.+)$/gm;
|
|
1198
|
+
var LIST_RE = /^(\s*)[-*]\s+(.+)$/gm;
|
|
1199
|
+
var LINK_RE = /\[([^\]]+)\]\(([^)]+)\)/g;
|
|
1200
|
+
function renderMarkdown(text) {
|
|
1201
|
+
let result = text;
|
|
1202
|
+
result = result.replace(CODE_BLOCK_RE, (_match, lang, code) => {
|
|
1203
|
+
const trimmed = code.trimEnd();
|
|
1204
|
+
const header = lang ? chalk6.gray(` \u2500\u2500 ${lang} \u2500\u2500`) : chalk6.gray(" \u2500\u2500 code \u2500\u2500");
|
|
1205
|
+
const lines = trimmed.split("\n").map((l) => chalk6.white(` ${l}`)).join("\n");
|
|
1206
|
+
return `
|
|
1207
|
+
${header}
|
|
1208
|
+
${lines}
|
|
1209
|
+
${chalk6.gray(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500")}
|
|
1210
|
+
`;
|
|
1211
|
+
});
|
|
1212
|
+
result = result.replace(INLINE_CODE_RE, (_m, code) => chalk6.cyan(`\`${code}\``));
|
|
1213
|
+
result = result.replace(BOLD_RE, (_m, text2) => chalk6.bold(text2));
|
|
1214
|
+
result = result.replace(HEADING_RE, (_m, hashes, text2) => {
|
|
1215
|
+
if (hashes.length === 1) return chalk6.bold.underline(text2);
|
|
1216
|
+
if (hashes.length === 2) return chalk6.bold(text2);
|
|
1217
|
+
return chalk6.bold.dim(text2);
|
|
1218
|
+
});
|
|
1219
|
+
result = result.replace(LIST_RE, (_m, indent, text2) => `${indent}${chalk6.cyan("\u2022")} ${text2}`);
|
|
1220
|
+
result = result.replace(LINK_RE, (_m, label, url) => `${chalk6.blue.underline(label)} ${chalk6.gray(`(${url})`)}`);
|
|
1221
|
+
return result;
|
|
1516
1222
|
}
|
|
1517
|
-
var tools, toolMap;
|
|
1518
|
-
var init_tools = __esm({
|
|
1519
|
-
"src/agent/tools/index.ts"() {
|
|
1520
|
-
"use strict";
|
|
1521
|
-
init_file_read();
|
|
1522
|
-
init_file_write();
|
|
1523
|
-
init_file_edit();
|
|
1524
|
-
init_bash();
|
|
1525
|
-
init_grep();
|
|
1526
|
-
init_list_files();
|
|
1527
|
-
init_sandbox();
|
|
1528
|
-
tools = [file_read_exports, file_write_exports, file_edit_exports, bash_exports, grep_exports, list_files_exports, sandbox_exports];
|
|
1529
|
-
toolMap = /* @__PURE__ */ new Map();
|
|
1530
|
-
for (const t of tools) {
|
|
1531
|
-
toolMap.set(t.definition.function.name, t);
|
|
1532
|
-
}
|
|
1533
|
-
}
|
|
1534
|
-
});
|
|
1535
1223
|
|
|
1536
|
-
// src/
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
join3(process.cwd(), ".mcp.json"),
|
|
1545
|
-
join3(process.env.HOME ?? "", ".mcp.json")
|
|
1546
|
-
].filter(Boolean);
|
|
1547
|
-
for (const p of searchPaths) {
|
|
1548
|
-
if (existsSync3(p)) {
|
|
1549
|
-
try {
|
|
1550
|
-
return JSON.parse(readFileSync4(p, "utf-8"));
|
|
1551
|
-
} catch {
|
|
1552
|
-
continue;
|
|
1553
|
-
}
|
|
1554
|
-
}
|
|
1224
|
+
// src/commands/workflow/run.ts
|
|
1225
|
+
async function workflowRun(workflowId, input, opts) {
|
|
1226
|
+
const auth = requireAuth();
|
|
1227
|
+
let workflowName = workflowId;
|
|
1228
|
+
try {
|
|
1229
|
+
const detail = await getWorkflowDetail(workflowId);
|
|
1230
|
+
workflowName = detail.workflow_name ?? workflowId;
|
|
1231
|
+
} catch {
|
|
1555
1232
|
}
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
requestId = 0;
|
|
1565
|
-
pending = /* @__PURE__ */ new Map();
|
|
1566
|
-
serverName;
|
|
1567
|
-
config;
|
|
1568
|
-
tools = [];
|
|
1569
|
-
constructor(serverName, config) {
|
|
1570
|
-
this.serverName = serverName;
|
|
1571
|
-
this.config = config;
|
|
1572
|
-
}
|
|
1573
|
-
async start() {
|
|
1574
|
-
this.process = spawn(this.config.command, this.config.args ?? [], {
|
|
1575
|
-
stdio: ["pipe", "pipe", "pipe"],
|
|
1576
|
-
env: { ...process.env, ...this.config.env }
|
|
1233
|
+
if (!input) {
|
|
1234
|
+
if (opts.interactive || !process.stdin.isTTY) {
|
|
1235
|
+
const { createInterface: createInterface7 } = await import("readline");
|
|
1236
|
+
const rl = createInterface7({ input: process.stdin, output: process.stdout });
|
|
1237
|
+
input = await new Promise((resolve) => {
|
|
1238
|
+
rl.question(chalk7.cyan("\uC785\uB825> "), (answer) => {
|
|
1239
|
+
rl.close();
|
|
1240
|
+
resolve(answer.trim());
|
|
1577
1241
|
});
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1242
|
+
});
|
|
1243
|
+
} else {
|
|
1244
|
+
printError("\uC785\uB825\uAC12\uC774 \uD544\uC694\uD569\uB2C8\uB2E4. \uC0AC\uC6A9\uBC95:");
|
|
1245
|
+
console.log(' xgen workflow run <id> "\uC785\uB825 \uD14D\uC2A4\uFFFD\uFFFD\uFFFD"');
|
|
1246
|
+
console.log(" xgen workflow run -i <id>");
|
|
1247
|
+
process.exit(1);
|
|
1248
|
+
}
|
|
1249
|
+
}
|
|
1250
|
+
if (!input) {
|
|
1251
|
+
printError("\uC785\uB825\uAC12\uC774 \uBE44\uC5B4\uC788\uC2B5\uB2C8\uB2E4");
|
|
1252
|
+
process.exit(1);
|
|
1253
|
+
}
|
|
1254
|
+
const interactionId = `cli_${randomUUID().slice(0, 8)}`;
|
|
1255
|
+
printHeader(`\uC2E4\uD589: ${workflowName}`);
|
|
1256
|
+
printInfo(`\uC785\uB825: ${input}`);
|
|
1257
|
+
console.log();
|
|
1258
|
+
try {
|
|
1259
|
+
const stream = await executeWorkflowStream({
|
|
1260
|
+
workflow_id: workflowId,
|
|
1261
|
+
workflow_name: workflowName,
|
|
1262
|
+
input_data: input,
|
|
1263
|
+
interaction_id: interactionId
|
|
1264
|
+
});
|
|
1265
|
+
let hasOutput = false;
|
|
1266
|
+
let fullResponse = "";
|
|
1267
|
+
await parseSSEStream(
|
|
1268
|
+
stream,
|
|
1269
|
+
(event) => {
|
|
1270
|
+
switch (event.type) {
|
|
1271
|
+
case "token":
|
|
1272
|
+
if (event.content) {
|
|
1273
|
+
if (!hasOutput) {
|
|
1274
|
+
hasOutput = true;
|
|
1275
|
+
console.log();
|
|
1589
1276
|
}
|
|
1277
|
+
process.stdout.write(event.content);
|
|
1278
|
+
fullResponse += event.content;
|
|
1279
|
+
}
|
|
1280
|
+
break;
|
|
1281
|
+
case "log":
|
|
1282
|
+
if (opts.logs && event.content) {
|
|
1283
|
+
process.stderr.write(chalk7.gray(`[LOG] ${event.content}
|
|
1284
|
+
`));
|
|
1285
|
+
}
|
|
1286
|
+
break;
|
|
1287
|
+
case "node_status":
|
|
1288
|
+
if (opts.logs) {
|
|
1289
|
+
const nodeName = event.node_name ?? event.node_id ?? "?";
|
|
1290
|
+
const status = event.status ?? "?";
|
|
1291
|
+
process.stderr.write(
|
|
1292
|
+
chalk7.gray(`[\uB178\uB4DC] ${nodeName}: ${status}
|
|
1293
|
+
`)
|
|
1294
|
+
);
|
|
1590
1295
|
}
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
reject(new Error(`MCP \uC694\uCCAD \uD0C0\uC784\uC544\uC6C3: ${method}`));
|
|
1612
|
-
}, 15e3);
|
|
1613
|
-
this.pending.set(id, {
|
|
1614
|
-
resolve: (v) => {
|
|
1615
|
-
clearTimeout(timeout);
|
|
1616
|
-
resolve(v);
|
|
1617
|
-
},
|
|
1618
|
-
reject: (e) => {
|
|
1619
|
-
clearTimeout(timeout);
|
|
1620
|
-
reject(e);
|
|
1296
|
+
break;
|
|
1297
|
+
case "tool":
|
|
1298
|
+
if (opts.logs) {
|
|
1299
|
+
process.stderr.write(chalk7.gray(`[\uB3C4\uAD6C] ${JSON.stringify(event.data)}
|
|
1300
|
+
`));
|
|
1301
|
+
}
|
|
1302
|
+
break;
|
|
1303
|
+
case "complete":
|
|
1304
|
+
break;
|
|
1305
|
+
case "error":
|
|
1306
|
+
console.log();
|
|
1307
|
+
printError(event.error ?? event.content ?? "\uC54C \uC218 \uC5C6\uB294 \uC624\uB958");
|
|
1308
|
+
break;
|
|
1309
|
+
default:
|
|
1310
|
+
if (event.content) {
|
|
1311
|
+
if (!hasOutput) {
|
|
1312
|
+
process.stdout.write(chalk7.green("\uC751\uB2F5: "));
|
|
1313
|
+
hasOutput = true;
|
|
1314
|
+
}
|
|
1315
|
+
process.stdout.write(event.content);
|
|
1621
1316
|
}
|
|
1622
|
-
});
|
|
1623
|
-
this.process?.stdin?.write(JSON.stringify(request) + "\n");
|
|
1624
|
-
});
|
|
1625
|
-
}
|
|
1626
|
-
async listTools() {
|
|
1627
|
-
const result = await this.send("tools/list", {});
|
|
1628
|
-
this.tools = result.tools ?? [];
|
|
1629
|
-
return this.tools;
|
|
1630
|
-
}
|
|
1631
|
-
async callTool(name, args) {
|
|
1632
|
-
const result = await this.send("tools/call", { name, arguments: args });
|
|
1633
|
-
return result.content?.map((c) => c.text ?? "").join("\n") ?? "";
|
|
1634
|
-
}
|
|
1635
|
-
getOpenAITools() {
|
|
1636
|
-
return this.tools.map((t) => ({
|
|
1637
|
-
type: "function",
|
|
1638
|
-
function: {
|
|
1639
|
-
name: `mcp_${this.serverName}_${t.name}`,
|
|
1640
|
-
description: `[MCP:${this.serverName}] ${t.description ?? t.name}`,
|
|
1641
|
-
parameters: t.inputSchema ?? { type: "object", properties: {} }
|
|
1642
|
-
}
|
|
1643
|
-
}));
|
|
1644
|
-
}
|
|
1645
|
-
stop() {
|
|
1646
|
-
this.process?.kill();
|
|
1647
|
-
this.process = null;
|
|
1648
|
-
}
|
|
1649
|
-
};
|
|
1650
|
-
McpManager = class {
|
|
1651
|
-
clients = /* @__PURE__ */ new Map();
|
|
1652
|
-
async startAll(config) {
|
|
1653
|
-
for (const [name, serverConfig] of Object.entries(config.mcpServers)) {
|
|
1654
|
-
if (serverConfig.type !== "stdio") continue;
|
|
1655
|
-
try {
|
|
1656
|
-
const client2 = new McpClient(name, serverConfig);
|
|
1657
|
-
await client2.start();
|
|
1658
|
-
await client2.listTools();
|
|
1659
|
-
this.clients.set(name, client2);
|
|
1660
|
-
} catch (err) {
|
|
1661
|
-
console.error(`MCP [${name}] \uC2DC\uC791 \uC2E4\uD328:`, err.message);
|
|
1662
|
-
}
|
|
1663
|
-
}
|
|
1664
|
-
}
|
|
1665
|
-
getAllTools() {
|
|
1666
|
-
const tools2 = [];
|
|
1667
|
-
for (const client2 of this.clients.values()) {
|
|
1668
|
-
tools2.push(...client2.getOpenAITools());
|
|
1669
1317
|
}
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
if (!client2) return `MCP \uC11C\uBC84\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${serverName}`;
|
|
1679
|
-
return client2.callTool(toolName, args);
|
|
1680
|
-
}
|
|
1681
|
-
isMcpTool(name) {
|
|
1682
|
-
return name.startsWith("mcp_");
|
|
1683
|
-
}
|
|
1684
|
-
stopAll() {
|
|
1685
|
-
for (const client2 of this.clients.values()) {
|
|
1686
|
-
client2.stop();
|
|
1318
|
+
},
|
|
1319
|
+
() => {
|
|
1320
|
+
if (hasOutput) {
|
|
1321
|
+
console.log();
|
|
1322
|
+
if (fullResponse.includes("```") || fullResponse.includes("**")) {
|
|
1323
|
+
console.log(chalk7.gray("\u2500".repeat(40)));
|
|
1324
|
+
console.log(renderMarkdown(fullResponse));
|
|
1325
|
+
}
|
|
1687
1326
|
}
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
return [...this.clients.keys()];
|
|
1327
|
+
console.log();
|
|
1328
|
+
console.log(chalk7.gray(`\uC138\uC158: ${interactionId}`));
|
|
1329
|
+
},
|
|
1330
|
+
(err) => {
|
|
1331
|
+
console.log();
|
|
1332
|
+
printError(`\uC2A4\uD2B8\uB9AC\uBC0D \uC624\uB958: ${err.message}`);
|
|
1695
1333
|
}
|
|
1696
|
-
|
|
1334
|
+
);
|
|
1335
|
+
} catch (err) {
|
|
1336
|
+
const msg = err?.response?.data?.detail ?? err.message;
|
|
1337
|
+
printError(`\uC2E4\uD589 \uC2E4\uD328: ${msg}`);
|
|
1338
|
+
process.exit(1);
|
|
1697
1339
|
}
|
|
1698
|
-
});
|
|
1699
|
-
|
|
1700
|
-
// src/api/document.ts
|
|
1701
|
-
var document_exports = {};
|
|
1702
|
-
__export(document_exports, {
|
|
1703
|
-
getDocumentInfo: () => getDocumentInfo,
|
|
1704
|
-
listDocuments: () => listDocuments,
|
|
1705
|
-
uploadDocument: () => uploadDocument
|
|
1706
|
-
});
|
|
1707
|
-
import { createReadStream, statSync } from "fs";
|
|
1708
|
-
import { basename } from "path";
|
|
1709
|
-
async function listDocuments(collectionId) {
|
|
1710
|
-
const client2 = getClient();
|
|
1711
|
-
const params = {};
|
|
1712
|
-
if (collectionId) params.collection_id = collectionId;
|
|
1713
|
-
const res = await client2.get("/api/documents/list", { params });
|
|
1714
|
-
return res.data.documents ?? res.data ?? [];
|
|
1715
1340
|
}
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1341
|
+
|
|
1342
|
+
// src/commands/workflow/history.ts
|
|
1343
|
+
init_store();
|
|
1344
|
+
init_workflow();
|
|
1345
|
+
init_format();
|
|
1346
|
+
import chalk8 from "chalk";
|
|
1347
|
+
async function workflowHistory(workflowId, opts = {}) {
|
|
1348
|
+
requireAuth();
|
|
1349
|
+
const limit = opts.limit ?? 20;
|
|
1350
|
+
try {
|
|
1351
|
+
const logs = await getIOLogs(workflowId, limit);
|
|
1352
|
+
if (!logs || logs.length === 0) {
|
|
1353
|
+
console.log(chalk8.yellow("\n\uC2E4\uD589 \uC774\uB825\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.\n"));
|
|
1354
|
+
return;
|
|
1355
|
+
}
|
|
1356
|
+
printHeader(`\uC2E4\uD589 \uC774\uB825 (\uCD5C\uADFC ${logs.length}\uAC74)`);
|
|
1357
|
+
console.log();
|
|
1358
|
+
for (const log of logs) {
|
|
1359
|
+
console.log(
|
|
1360
|
+
` ${chalk8.gray(formatDate(log.created_at))} ${chalk8.cyan(log.interaction_id)}`
|
|
1361
|
+
);
|
|
1362
|
+
console.log(` ${chalk8.white("\uC785\uB825:")} ${truncate(log.input_data, 60)}`);
|
|
1363
|
+
console.log(
|
|
1364
|
+
` ${chalk8.green("\uCD9C\uB825:")} ${truncate(log.output_data, 60)}`
|
|
1365
|
+
);
|
|
1366
|
+
if (log.execution_time) {
|
|
1367
|
+
console.log(
|
|
1368
|
+
` ${chalk8.gray("\uC2DC\uAC04:")} ${(log.execution_time / 1e3).toFixed(1)}s`
|
|
1369
|
+
);
|
|
1370
|
+
}
|
|
1371
|
+
console.log();
|
|
1372
|
+
}
|
|
1373
|
+
} catch (err) {
|
|
1374
|
+
const msg = err.message;
|
|
1375
|
+
printError(`\uC774\uB825 \uC870\uD68C \uC2E4\uD328: ${msg}`);
|
|
1376
|
+
process.exit(1);
|
|
1377
|
+
}
|
|
1731
1378
|
}
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1379
|
+
|
|
1380
|
+
// src/commands/workflow/index.ts
|
|
1381
|
+
function registerWorkflowCommand(program2) {
|
|
1382
|
+
const wf = program2.command("workflow").alias("wf").description("\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uAD00\uB9AC \uBC0F \uC2E4\uD589");
|
|
1383
|
+
wf.command("list").alias("ls").description("\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uBAA9\uB85D \uC870\uD68C").option("-d, --detail", "\uC0C1\uC138 \uC815\uBCF4 \uD3EC\uD568").action((opts) => workflowList(opts));
|
|
1384
|
+
wf.command("info <workflow-id>").description("\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uC0C1\uC138 \uC815\uBCF4").action((id) => workflowInfo(id));
|
|
1385
|
+
wf.command("run <workflow-id> [input]").description("\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uC2E4\uD589").option("-i, --interactive", "\uC778\uD130\uB799\uD2F0\uBE0C \uBAA8\uB4DC (\uC785\uB825 \uD504\uB86C\uD504\uD2B8)").option("-l, --logs", "\uB514\uBC84\uADF8 \uB85C\uADF8 \uD45C\uC2DC").action((id, input, opts) => workflowRun(id, input, opts));
|
|
1386
|
+
wf.command("history [workflow-id]").description("\uC2E4\uD589 \uC774\uB825 \uC870\uD68C").option("-n, --limit <number>", "\uC870\uD68C \uAC74\uC218", "20").action((id, opts) => workflowHistory(id, { limit: parseInt(opts.limit) }));
|
|
1736
1387
|
}
|
|
1737
|
-
var init_document = __esm({
|
|
1738
|
-
"src/api/document.ts"() {
|
|
1739
|
-
"use strict";
|
|
1740
|
-
init_client();
|
|
1741
|
-
}
|
|
1742
|
-
});
|
|
1743
1388
|
|
|
1744
|
-
// src/
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1389
|
+
// src/commands/chat.ts
|
|
1390
|
+
init_store();
|
|
1391
|
+
init_workflow();
|
|
1392
|
+
import chalk9 from "chalk";
|
|
1393
|
+
import { createInterface as createInterface2 } from "readline";
|
|
1394
|
+
import { randomUUID as randomUUID2 } from "crypto";
|
|
1395
|
+
init_format();
|
|
1396
|
+
var CHAT_BANNER = `
|
|
1397
|
+
${chalk9.cyan("\u256D\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256E")}
|
|
1398
|
+
${chalk9.cyan("\u2502")} ${chalk9.white.bold("XGEN")} ${chalk9.gray("\u2014 \uC6CC\uD06C\uD50C\uB85C\uC6B0 AI \uD130\uBBF8\uB110")} ${chalk9.cyan("\u2502")}
|
|
1399
|
+
${chalk9.cyan("\u2502")} ${chalk9.gray("/help \uB3C4\uC6C0\uB9D0 /workflows \uC804\uD658 /exit")} ${chalk9.cyan("\u2502")}
|
|
1400
|
+
${chalk9.cyan("\u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256F")}`;
|
|
1401
|
+
function printHelp() {
|
|
1402
|
+
console.log(`
|
|
1403
|
+
${chalk9.bold("\uC2AC\uB798\uC2DC \uCEE4\uB9E8\uB4DC")}
|
|
1404
|
+
${chalk9.cyan("/workflows")} \uC6CC\uD06C\uD50C\uB85C\uC6B0 \uBAA9\uB85D \uBCF4\uAE30 & \uC804\uD658
|
|
1405
|
+
${chalk9.cyan("/switch")} \uC6CC\uD06C\uD50C\uB85C\uC6B0 \uBC88\uD638\uB85C \uC804\uD658 (\uC608: /switch 3)
|
|
1406
|
+
${chalk9.cyan("/history")} \uD604\uC7AC \uC138\uC158 \uB300\uD654 \uC774\uB825
|
|
1407
|
+
${chalk9.cyan("/clear")} \uD654\uBA74 \uC9C0\uC6B0\uAE30
|
|
1408
|
+
${chalk9.cyan("/info")} \uD604\uC7AC \uC5F0\uACB0 \uC815\uBCF4
|
|
1409
|
+
${chalk9.cyan("/help")} \uC774 \uB3C4\uC6C0\uB9D0
|
|
1410
|
+
${chalk9.cyan("/exit")} \uC885\uB8CC (Ctrl+C\uB3C4 \uAC00\uB2A5)
|
|
1411
|
+
`);
|
|
1760
1412
|
}
|
|
1761
|
-
async function
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
query,
|
|
1765
|
-
session_id: sessionId,
|
|
1766
|
-
graph_id: graphId,
|
|
1767
|
-
max_turns: opts?.maxTurns ?? 5
|
|
1413
|
+
async function promptLine(rl, promptStr) {
|
|
1414
|
+
return new Promise((resolve) => {
|
|
1415
|
+
rl.question(promptStr, (answer) => resolve(answer));
|
|
1768
1416
|
});
|
|
1769
|
-
return res.data;
|
|
1770
|
-
}
|
|
1771
|
-
async function getGraphStats(graphId) {
|
|
1772
|
-
const client2 = getClient();
|
|
1773
|
-
const res = await client2.get(`/api/graph/${graphId}/stats`);
|
|
1774
|
-
return res.data;
|
|
1775
1417
|
}
|
|
1776
|
-
async function
|
|
1777
|
-
const
|
|
1778
|
-
const res = await client2.get("/api/graph/list");
|
|
1779
|
-
return res.data.graphs ?? res.data ?? [];
|
|
1780
|
-
}
|
|
1781
|
-
var init_ontology = __esm({
|
|
1782
|
-
"src/api/ontology.ts"() {
|
|
1783
|
-
"use strict";
|
|
1784
|
-
init_client();
|
|
1785
|
-
}
|
|
1786
|
-
});
|
|
1787
|
-
|
|
1788
|
-
// src/commands/home.ts
|
|
1789
|
-
var home_exports = {};
|
|
1790
|
-
__export(home_exports, {
|
|
1791
|
-
homeMenu: () => homeMenu
|
|
1792
|
-
});
|
|
1793
|
-
import chalk12 from "chalk";
|
|
1794
|
-
function showStatus() {
|
|
1795
|
-
const provider = getDefaultProvider();
|
|
1418
|
+
async function chat(workflowId) {
|
|
1419
|
+
const auth = requireAuth();
|
|
1796
1420
|
const server = getServer();
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
if (
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1421
|
+
let workflows = [];
|
|
1422
|
+
try {
|
|
1423
|
+
workflows = await listWorkflows();
|
|
1424
|
+
} catch {
|
|
1425
|
+
printError("\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uBAA9\uB85D\uC744 \uBD88\uB7EC\uC62C \uC218 \uC5C6\uC2B5\uB2C8\uB2E4");
|
|
1426
|
+
process.exit(1);
|
|
1427
|
+
}
|
|
1428
|
+
if (workflows.length === 0) {
|
|
1429
|
+
printError("\uC0AC\uC6A9 \uAC00\uB2A5\uD55C \uC6CC\uD06C\uD50C\uB85C\uC6B0\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4");
|
|
1430
|
+
process.exit(1);
|
|
1431
|
+
}
|
|
1432
|
+
let current;
|
|
1433
|
+
if (workflowId) {
|
|
1434
|
+
const found = workflows.find((w) => w.id === workflowId || w.workflow_name === workflowId);
|
|
1435
|
+
current = found ?? { id: workflowId, workflow_name: workflowId };
|
|
1436
|
+
} else {
|
|
1437
|
+
console.log(CHAT_BANNER);
|
|
1438
|
+
console.log(chalk9.gray(` \uC11C\uBC84: ${server} | \uC0AC\uC6A9\uC790: ${auth.username}
|
|
1439
|
+
`));
|
|
1440
|
+
console.log(chalk9.bold(" \uC6CC\uD06C\uD50C\uB85C\uC6B0 \uC120\uD0DD:\n"));
|
|
1441
|
+
workflows.forEach((w, i) => {
|
|
1442
|
+
console.log(` ${chalk9.cyan(String(i + 1).padStart(3))} ${w.workflow_name}`);
|
|
1443
|
+
});
|
|
1444
|
+
console.log();
|
|
1445
|
+
const rl2 = createInterface2({ input: process.stdin, output: process.stdout });
|
|
1446
|
+
const answer = await promptLine(rl2, chalk9.cyan(" \uBC88\uD638> "));
|
|
1447
|
+
rl2.close();
|
|
1448
|
+
const idx = parseInt(answer.trim()) - 1;
|
|
1449
|
+
if (isNaN(idx) || idx < 0 || idx >= workflows.length) {
|
|
1450
|
+
current = workflows[0];
|
|
1451
|
+
} else {
|
|
1452
|
+
current = workflows[idx];
|
|
1453
|
+
}
|
|
1808
1454
|
}
|
|
1455
|
+
const sessionId = randomUUID2().slice(0, 8);
|
|
1456
|
+
let turnCount = 0;
|
|
1457
|
+
const history = [];
|
|
1809
1458
|
console.log();
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
console.log(
|
|
1813
|
-
console.log(
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
const
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1459
|
+
console.log(chalk9.cyan("\u2500".repeat(42)));
|
|
1460
|
+
console.log(chalk9.white.bold(` ${current.workflow_name}`));
|
|
1461
|
+
console.log(chalk9.cyan("\u2500".repeat(42)));
|
|
1462
|
+
console.log(chalk9.gray(" \uBA54\uC2DC\uC9C0\uB97C \uC785\uB825\uD558\uC138\uC694. /help \uB85C \uB3C4\uC6C0\uB9D0.\n"));
|
|
1463
|
+
const rl = createInterface2({
|
|
1464
|
+
input: process.stdin,
|
|
1465
|
+
output: process.stdout
|
|
1466
|
+
});
|
|
1467
|
+
const getPrompt = () => chalk9.cyan("\u276F ");
|
|
1468
|
+
const processInput = async (line) => {
|
|
1469
|
+
const input = line.trim();
|
|
1470
|
+
if (!input) return;
|
|
1471
|
+
if (input.startsWith("/")) {
|
|
1472
|
+
const [cmd, ...args] = input.slice(1).split(" ");
|
|
1473
|
+
switch (cmd.toLowerCase()) {
|
|
1474
|
+
case "exit":
|
|
1475
|
+
case "quit":
|
|
1476
|
+
case "q":
|
|
1477
|
+
console.log(chalk9.gray("\n \uC885\uB8CC\uD569\uB2C8\uB2E4.\n"));
|
|
1478
|
+
rl.close();
|
|
1479
|
+
process.exit(0);
|
|
1480
|
+
break;
|
|
1481
|
+
case "help":
|
|
1482
|
+
case "h":
|
|
1483
|
+
printHelp();
|
|
1484
|
+
break;
|
|
1485
|
+
case "clear":
|
|
1486
|
+
case "cls":
|
|
1487
|
+
console.clear();
|
|
1488
|
+
console.log(chalk9.white.bold(` ${current.workflow_name}`));
|
|
1489
|
+
console.log(chalk9.cyan("\u2500".repeat(42)));
|
|
1490
|
+
break;
|
|
1491
|
+
case "workflows":
|
|
1492
|
+
case "wf":
|
|
1838
1493
|
console.log();
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
items.push({
|
|
1843
|
-
key: "w",
|
|
1844
|
-
label: "\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uAD00\uB9AC",
|
|
1845
|
-
hint: "\uBAA9\uB85D \uC870\uD68C \u2192 \uC120\uD0DD \u2192 \uC2E4\uD589/\uC815\uBCF4",
|
|
1846
|
-
action: async () => {
|
|
1847
|
-
const { getWorkflowListDetail: getWorkflowListDetail2 } = await Promise.resolve().then(() => (init_workflow(), workflow_exports));
|
|
1848
|
-
const wfs = await getWorkflowListDetail2();
|
|
1849
|
-
if (!wfs.length) {
|
|
1850
|
-
console.log(chalk12.yellow("\n \uC6CC\uD06C\uD50C\uB85C\uC6B0\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.\n"));
|
|
1851
|
-
return;
|
|
1852
|
-
}
|
|
1853
|
-
console.log(chalk12.bold(`
|
|
1854
|
-
\uC6CC\uD06C\uD50C\uB85C\uC6B0 (${wfs.length}\uAC1C)
|
|
1855
|
-
`));
|
|
1856
|
-
wfs.forEach((w, i) => {
|
|
1857
|
-
const id = (w.workflow_id ?? w.id ?? "").toString();
|
|
1858
|
-
const deployed = w.is_deployed;
|
|
1859
|
-
const tag = deployed ? chalk12.green(" [\uBC30\uD3EC]") : "";
|
|
1860
|
-
console.log(` ${chalk12.cyan(`${String(i + 1).padStart(3)}.`)} ${w.workflow_name}${tag}`);
|
|
1861
|
-
console.log(` ${chalk12.gray(id)}`);
|
|
1494
|
+
workflows.forEach((w, i) => {
|
|
1495
|
+
const marker = w.id === current.id ? chalk9.green("\u25B8") : " ";
|
|
1496
|
+
console.log(` ${marker} ${chalk9.cyan(String(i + 1).padStart(2))} ${w.workflow_name}`);
|
|
1862
1497
|
});
|
|
1863
|
-
console.log();
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
const
|
|
1868
|
-
if (
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
const deployKey = selected2.deploy_key;
|
|
1877
|
-
const isDeployed = selected2.is_deployed;
|
|
1878
|
-
try {
|
|
1879
|
-
console.log(chalk12.gray("\n \uC2E4\uD589 \uC911...\n"));
|
|
1880
|
-
const { executeWorkflow: executeWorkflow2 } = await Promise.resolve().then(() => (init_workflow(), workflow_exports));
|
|
1881
|
-
const { randomUUID: randomUUID4 } = await import("crypto");
|
|
1882
|
-
const result = await executeWorkflow2({
|
|
1883
|
-
workflow_id: wfId,
|
|
1884
|
-
workflow_name: selected2.workflow_name,
|
|
1885
|
-
input_data: input,
|
|
1886
|
-
interaction_id: `cli_${randomUUID4().slice(0, 8)}`,
|
|
1887
|
-
deploy_key: isDeployed && deployKey ? deployKey : void 0
|
|
1888
|
-
});
|
|
1889
|
-
if (result.content) {
|
|
1890
|
-
console.log(chalk12.bold(" \uC751\uB2F5:"));
|
|
1891
|
-
console.log(` ${result.content}
|
|
1892
|
-
`);
|
|
1893
|
-
} else if (result.success === false) {
|
|
1894
|
-
console.log(chalk12.red(` \uC624\uB958: ${result.error ?? result.message}
|
|
1895
|
-
`));
|
|
1896
|
-
} else {
|
|
1897
|
-
console.log(chalk12.gray(JSON.stringify(result, null, 2).slice(0, 500)));
|
|
1898
|
-
console.log();
|
|
1899
|
-
}
|
|
1900
|
-
} catch (err) {
|
|
1901
|
-
console.log(chalk12.red(` \uC2E4\uD589 \uC2E4\uD328: ${err.message}
|
|
1498
|
+
console.log(chalk9.gray("\n /switch <\uBC88\uD638> \uB85C \uC804\uD658\n"));
|
|
1499
|
+
break;
|
|
1500
|
+
case "switch":
|
|
1501
|
+
case "sw": {
|
|
1502
|
+
const num = parseInt(args[0]);
|
|
1503
|
+
if (isNaN(num) || num < 1 || num > workflows.length) {
|
|
1504
|
+
console.log(chalk9.yellow(` 1~${workflows.length} \uC0AC\uC774 \uBC88\uD638\uB97C \uC785\uB825\uD558\uC138\uC694`));
|
|
1505
|
+
} else {
|
|
1506
|
+
current = workflows[num - 1];
|
|
1507
|
+
turnCount = 0;
|
|
1508
|
+
history.length = 0;
|
|
1509
|
+
console.log(chalk9.green(`
|
|
1510
|
+
\uC804\uD658: ${current.workflow_name}
|
|
1902
1511
|
`));
|
|
1903
1512
|
}
|
|
1513
|
+
break;
|
|
1904
1514
|
}
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
action: async () => {
|
|
1911
|
-
try {
|
|
1912
|
-
const { listDocuments: listDocuments2 } = await Promise.resolve().then(() => (init_document(), document_exports));
|
|
1913
|
-
const docs = await listDocuments2();
|
|
1914
|
-
if (!docs.length) {
|
|
1915
|
-
console.log(chalk12.yellow("\n \uBB38\uC11C\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.\n"));
|
|
1916
|
-
return;
|
|
1917
|
-
}
|
|
1918
|
-
console.log(chalk12.bold(`
|
|
1919
|
-
\uBB38\uC11C (${docs.length}\uAC1C)
|
|
1920
|
-
`));
|
|
1921
|
-
docs.forEach((d, i) => {
|
|
1922
|
-
console.log(` ${chalk12.cyan(`${i + 1}.`)} ${d.file_name ?? d.name ?? "-"} ${chalk12.gray(d.file_type ?? "")}`);
|
|
1923
|
-
});
|
|
1515
|
+
case "history":
|
|
1516
|
+
case "hist":
|
|
1517
|
+
if (history.length === 0) {
|
|
1518
|
+
console.log(chalk9.gray(" \uB300\uD654 \uC774\uB825\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.\n"));
|
|
1519
|
+
} else {
|
|
1924
1520
|
console.log();
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
}
|
|
1930
|
-
});
|
|
1931
|
-
items.push({
|
|
1932
|
-
key: "o",
|
|
1933
|
-
label: "\uC628\uD1A8\uB85C\uC9C0 \uC9C8\uC758",
|
|
1934
|
-
hint: "GraphRAG \uC6D0\uC0F7 \uC9C8\uC758",
|
|
1935
|
-
action: async () => {
|
|
1936
|
-
const question = await ask(chalk12.white("\n \uC9C8\uBB38: "));
|
|
1937
|
-
if (!question) return;
|
|
1938
|
-
try {
|
|
1939
|
-
console.log(chalk12.gray(" \uC9C8\uC758 \uC911...\n"));
|
|
1940
|
-
const { queryGraphRAG: queryGraphRAG2 } = await Promise.resolve().then(() => (init_ontology(), ontology_exports));
|
|
1941
|
-
const result = await queryGraphRAG2(question);
|
|
1942
|
-
if (result.answer) {
|
|
1943
|
-
console.log(chalk12.bold(" \uB2F5\uBCC0:"));
|
|
1944
|
-
console.log(` ${result.answer}`);
|
|
1945
|
-
}
|
|
1946
|
-
if (result.sources?.length) {
|
|
1947
|
-
console.log(chalk12.bold("\n \uCD9C\uCC98:"));
|
|
1948
|
-
result.sources.forEach((s) => console.log(chalk12.gray(` - ${s}`)));
|
|
1521
|
+
for (const h of history) {
|
|
1522
|
+
const label = h.role === "user" ? chalk9.cyan("\uB098") : chalk9.green("AI");
|
|
1523
|
+
const text = h.content.length > 80 ? h.content.slice(0, 80) + "..." : h.content;
|
|
1524
|
+
console.log(` ${label}: ${text}`);
|
|
1949
1525
|
}
|
|
1950
1526
|
console.log();
|
|
1951
|
-
} catch (err) {
|
|
1952
|
-
console.log(chalk12.red(` \uC624\uB958: ${err.message}
|
|
1953
|
-
`));
|
|
1954
1527
|
}
|
|
1955
|
-
|
|
1528
|
+
break;
|
|
1529
|
+
case "info":
|
|
1530
|
+
console.log(`
|
|
1531
|
+
${chalk9.gray("\uC11C\uBC84:")} ${server}
|
|
1532
|
+
${chalk9.gray("\uC0AC\uC6A9\uC790:")} ${auth.username}
|
|
1533
|
+
${chalk9.gray("\uC6CC\uD06C\uD50C\uB85C\uC6B0:")} ${current.workflow_name}
|
|
1534
|
+
${chalk9.gray("\uC138\uC158:")} ${sessionId}
|
|
1535
|
+
${chalk9.gray("\uD134:")} ${turnCount}
|
|
1536
|
+
`);
|
|
1537
|
+
break;
|
|
1538
|
+
default:
|
|
1539
|
+
console.log(chalk9.yellow(` \uC54C \uC218 \uC5C6\uB294 \uCEE4\uB9E8\uB4DC: /${cmd}. /help \uCC38\uACE0`));
|
|
1540
|
+
}
|
|
1541
|
+
rl.prompt();
|
|
1542
|
+
return;
|
|
1543
|
+
}
|
|
1544
|
+
turnCount++;
|
|
1545
|
+
const interactionId = `${sessionId}_t${turnCount}`;
|
|
1546
|
+
history.push({ role: "user", content: input });
|
|
1547
|
+
process.stdout.write(chalk9.gray(" thinking..."));
|
|
1548
|
+
try {
|
|
1549
|
+
const stream = await executeWorkflowStream({
|
|
1550
|
+
workflow_id: current.id,
|
|
1551
|
+
workflow_name: current.workflow_name,
|
|
1552
|
+
input_data: input,
|
|
1553
|
+
interaction_id: interactionId
|
|
1956
1554
|
});
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
console.log(
|
|
1967
|
-
return;
|
|
1555
|
+
process.stdout.write("\r" + " ".repeat(20) + "\r");
|
|
1556
|
+
let fullResponse = "";
|
|
1557
|
+
let hasOutput = false;
|
|
1558
|
+
await parseSSEStream(
|
|
1559
|
+
stream,
|
|
1560
|
+
(event) => {
|
|
1561
|
+
if ((event.type === "token" || !event.type) && event.content) {
|
|
1562
|
+
if (!hasOutput) {
|
|
1563
|
+
hasOutput = true;
|
|
1564
|
+
console.log();
|
|
1968
1565
|
}
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1566
|
+
process.stdout.write(event.content);
|
|
1567
|
+
fullResponse += event.content;
|
|
1568
|
+
} else if (event.type === "error") {
|
|
1569
|
+
process.stdout.write("\r" + " ".repeat(20) + "\r");
|
|
1570
|
+
printError(event.error ?? event.content ?? "\uC624\uB958");
|
|
1571
|
+
}
|
|
1572
|
+
},
|
|
1573
|
+
() => {
|
|
1574
|
+
if (hasOutput) {
|
|
1977
1575
|
console.log();
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1576
|
+
console.log();
|
|
1577
|
+
}
|
|
1578
|
+
if (fullResponse) {
|
|
1579
|
+
history.push({ role: "assistant", content: fullResponse });
|
|
1981
1580
|
}
|
|
1581
|
+
},
|
|
1582
|
+
(err) => {
|
|
1583
|
+
process.stdout.write("\r" + " ".repeat(20) + "\r");
|
|
1584
|
+
printError(`\uC2A4\uD2B8\uB9AC\uBC0D \uC624\uB958: ${err.message}`);
|
|
1982
1585
|
}
|
|
1983
|
-
|
|
1586
|
+
);
|
|
1587
|
+
} catch (err) {
|
|
1588
|
+
process.stdout.write("\r" + " ".repeat(20) + "\r");
|
|
1589
|
+
const msg = err?.response?.data?.detail ?? err.message;
|
|
1590
|
+
printError(`\uC2E4\uD589 \uC2E4\uD328: ${msg}`);
|
|
1984
1591
|
}
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
showStatus();
|
|
1992
|
-
}
|
|
1993
|
-
});
|
|
1994
|
-
items.push({
|
|
1995
|
-
key: "p",
|
|
1996
|
-
label: "\uD504\uB85C\uBC14\uC774\uB354 \uAD00\uB9AC",
|
|
1997
|
-
hint: `${getProviders().length}\uAC1C \uB4F1\uB85D`,
|
|
1998
|
-
action: async () => {
|
|
1999
|
-
await providerMenu();
|
|
2000
|
-
showStatus();
|
|
2001
|
-
}
|
|
2002
|
-
});
|
|
2003
|
-
items.push({
|
|
2004
|
-
key: "e",
|
|
2005
|
-
label: "\uD658\uACBD \uAD00\uB9AC",
|
|
2006
|
-
hint: `${getEnvironments().length}\uAC1C \uB4F1\uB85D \u2014 \uC11C\uBC84 \uC804\uD658`,
|
|
2007
|
-
action: async () => {
|
|
2008
|
-
await environmentMenu();
|
|
2009
|
-
showStatus();
|
|
2010
|
-
}
|
|
1592
|
+
rl.prompt();
|
|
1593
|
+
};
|
|
1594
|
+
rl.setPrompt(getPrompt());
|
|
1595
|
+
rl.prompt();
|
|
1596
|
+
rl.on("line", (line) => {
|
|
1597
|
+
processInput(line).then(() => {
|
|
2011
1598
|
});
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
1599
|
+
});
|
|
1600
|
+
rl.on("close", () => {
|
|
1601
|
+
console.log(chalk9.gray("\n \uC885\uB8CC\uD569\uB2C8\uB2E4.\n"));
|
|
1602
|
+
process.exit(0);
|
|
1603
|
+
});
|
|
1604
|
+
process.on("SIGINT", () => {
|
|
1605
|
+
console.log(chalk9.gray("\n \uC885\uB8CC\uD569\uB2C8\uB2E4.\n"));
|
|
1606
|
+
process.exit(0);
|
|
1607
|
+
});
|
|
1608
|
+
}
|
|
1609
|
+
function registerChatCommand(program2) {
|
|
1610
|
+
program2.command("chat [workflow-id]").description("\uC778\uD130\uB799\uD2F0\uBE0C \uB300\uD654 \uBAA8\uB4DC").action((workflowId) => chat(workflowId));
|
|
1611
|
+
}
|
|
1612
|
+
|
|
1613
|
+
// src/index.ts
|
|
1614
|
+
init_provider();
|
|
1615
|
+
|
|
1616
|
+
// src/commands/agent.ts
|
|
1617
|
+
init_store();
|
|
1618
|
+
import chalk12 from "chalk";
|
|
1619
|
+
import { createInterface as createInterface5 } from "readline";
|
|
1620
|
+
|
|
1621
|
+
// src/agent/llm.ts
|
|
1622
|
+
import OpenAI2 from "openai";
|
|
1623
|
+
function createLLMClient(provider) {
|
|
1624
|
+
const opts = {
|
|
1625
|
+
apiKey: provider.apiKey || "ollama"
|
|
1626
|
+
};
|
|
1627
|
+
if (provider.baseUrl) {
|
|
1628
|
+
opts.baseURL = provider.baseUrl;
|
|
1629
|
+
}
|
|
1630
|
+
return new OpenAI2(opts);
|
|
1631
|
+
}
|
|
1632
|
+
async function streamChat(client2, model, messages, tools2, onDelta) {
|
|
1633
|
+
const params = {
|
|
1634
|
+
model,
|
|
1635
|
+
messages,
|
|
1636
|
+
stream: true
|
|
1637
|
+
};
|
|
1638
|
+
if (tools2 && tools2.length > 0) {
|
|
1639
|
+
params.tools = tools2;
|
|
1640
|
+
}
|
|
1641
|
+
const stream = await client2.chat.completions.create(params);
|
|
1642
|
+
let content = "";
|
|
1643
|
+
const toolCallMap = /* @__PURE__ */ new Map();
|
|
1644
|
+
for await (const chunk of stream) {
|
|
1645
|
+
const delta = chunk.choices[0]?.delta;
|
|
1646
|
+
if (!delta) continue;
|
|
1647
|
+
if (delta.content) {
|
|
1648
|
+
content += delta.content;
|
|
1649
|
+
onDelta?.(delta.content);
|
|
2016
1650
|
}
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
1651
|
+
if (delta.tool_calls) {
|
|
1652
|
+
for (const tc of delta.tool_calls) {
|
|
1653
|
+
const idx = tc.index;
|
|
1654
|
+
if (!toolCallMap.has(idx)) {
|
|
1655
|
+
toolCallMap.set(idx, { id: tc.id ?? "", name: tc.function?.name ?? "", arguments: "" });
|
|
1656
|
+
}
|
|
1657
|
+
const entry = toolCallMap.get(idx);
|
|
1658
|
+
if (tc.id) entry.id = tc.id;
|
|
1659
|
+
if (tc.function?.name) entry.name = tc.function.name;
|
|
1660
|
+
if (tc.function?.arguments) entry.arguments += tc.function.arguments;
|
|
2024
1661
|
}
|
|
2025
1662
|
}
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
1663
|
+
}
|
|
1664
|
+
return {
|
|
1665
|
+
content,
|
|
1666
|
+
toolCalls: [...toolCallMap.values()]
|
|
1667
|
+
};
|
|
1668
|
+
}
|
|
1669
|
+
|
|
1670
|
+
// src/agent/tools/file-read.ts
|
|
1671
|
+
var file_read_exports = {};
|
|
1672
|
+
__export(file_read_exports, {
|
|
1673
|
+
definition: () => definition,
|
|
1674
|
+
execute: () => execute
|
|
1675
|
+
});
|
|
1676
|
+
import { readFileSync as readFileSync2 } from "fs";
|
|
1677
|
+
var definition = {
|
|
1678
|
+
type: "function",
|
|
1679
|
+
function: {
|
|
1680
|
+
name: "file_read",
|
|
1681
|
+
description: "\uD30C\uC77C \uB0B4\uC6A9\uC744 \uC77D\uC2B5\uB2C8\uB2E4. \uC904 \uBC88\uD638\uAC00 \uD3EC\uD568\uB429\uB2C8\uB2E4.",
|
|
1682
|
+
parameters: {
|
|
1683
|
+
type: "object",
|
|
1684
|
+
properties: {
|
|
1685
|
+
path: { type: "string", description: "\uD30C\uC77C \uACBD\uB85C" },
|
|
1686
|
+
start_line: { type: "number", description: "\uC2DC\uC791 \uC904 \uBC88\uD638 (\uC120\uD0DD)" },
|
|
1687
|
+
end_line: { type: "number", description: "\uB05D \uC904 \uBC88\uD638 (\uC120\uD0DD)" }
|
|
1688
|
+
},
|
|
1689
|
+
required: ["path"]
|
|
2051
1690
|
}
|
|
2052
1691
|
}
|
|
2053
|
-
}
|
|
2054
|
-
async function
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
return;
|
|
1692
|
+
};
|
|
1693
|
+
async function execute(args) {
|
|
1694
|
+
const path = args.path;
|
|
1695
|
+
const startLine = args.start_line || 1;
|
|
1696
|
+
const endLine = args.end_line;
|
|
1697
|
+
try {
|
|
1698
|
+
const content = readFileSync2(path, "utf-8");
|
|
1699
|
+
const lines = content.split("\n");
|
|
1700
|
+
const sliced = lines.slice(startLine - 1, endLine ?? lines.length);
|
|
1701
|
+
return sliced.map((line, i) => `${startLine + i} ${line}`).join("\n");
|
|
1702
|
+
} catch (err) {
|
|
1703
|
+
return `Error: ${err.message}`;
|
|
2066
1704
|
}
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
1705
|
+
}
|
|
1706
|
+
|
|
1707
|
+
// src/agent/tools/file-write.ts
|
|
1708
|
+
var file_write_exports = {};
|
|
1709
|
+
__export(file_write_exports, {
|
|
1710
|
+
definition: () => definition2,
|
|
1711
|
+
execute: () => execute2
|
|
1712
|
+
});
|
|
1713
|
+
import { writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "fs";
|
|
1714
|
+
import { dirname } from "path";
|
|
1715
|
+
var definition2 = {
|
|
1716
|
+
type: "function",
|
|
1717
|
+
function: {
|
|
1718
|
+
name: "file_write",
|
|
1719
|
+
description: "\uD30C\uC77C\uC744 \uC0DD\uC131\uD558\uAC70\uB098 \uB36E\uC5B4\uC501\uB2C8\uB2E4.",
|
|
1720
|
+
parameters: {
|
|
1721
|
+
type: "object",
|
|
1722
|
+
properties: {
|
|
1723
|
+
path: { type: "string", description: "\uD30C\uC77C \uACBD\uB85C" },
|
|
1724
|
+
content: { type: "string", description: "\uD30C\uC77C \uB0B4\uC6A9" }
|
|
1725
|
+
},
|
|
1726
|
+
required: ["path", "content"]
|
|
1727
|
+
}
|
|
2076
1728
|
}
|
|
1729
|
+
};
|
|
1730
|
+
async function execute2(args) {
|
|
1731
|
+
const path = args.path;
|
|
1732
|
+
const content = args.content;
|
|
2077
1733
|
try {
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
if (result.success && result.access_token) {
|
|
2082
|
-
setAuth2({
|
|
2083
|
-
accessToken: result.access_token,
|
|
2084
|
-
refreshToken: result.refresh_token ?? "",
|
|
2085
|
-
userId: result.user_id ?? "",
|
|
2086
|
-
username: result.username ?? "",
|
|
2087
|
-
isAdmin: false,
|
|
2088
|
-
expiresAt: null
|
|
2089
|
-
});
|
|
2090
|
-
console.log(chalk12.green(`
|
|
2091
|
-
\u2713 \uB85C\uADF8\uC778 \uC131\uACF5! ${chalk12.bold(result.username ?? email)}
|
|
2092
|
-
`));
|
|
2093
|
-
} else {
|
|
2094
|
-
console.log(chalk12.red(`
|
|
2095
|
-
\u2717 ${result.message}
|
|
2096
|
-
`));
|
|
2097
|
-
}
|
|
1734
|
+
mkdirSync2(dirname(path), { recursive: true });
|
|
1735
|
+
writeFileSync2(path, content, "utf-8");
|
|
1736
|
+
return `\uD30C\uC77C \uC791\uC131 \uC644\uB8CC: ${path}`;
|
|
2098
1737
|
} catch (err) {
|
|
2099
|
-
|
|
2100
|
-
\u2717 ${err.message}
|
|
2101
|
-
`));
|
|
1738
|
+
return `Error: ${err.message}`;
|
|
2102
1739
|
}
|
|
2103
1740
|
}
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
1741
|
+
|
|
1742
|
+
// src/agent/tools/file-edit.ts
|
|
1743
|
+
var file_edit_exports = {};
|
|
1744
|
+
__export(file_edit_exports, {
|
|
1745
|
+
definition: () => definition3,
|
|
1746
|
+
execute: () => execute3
|
|
1747
|
+
});
|
|
1748
|
+
import { readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
|
|
1749
|
+
var definition3 = {
|
|
1750
|
+
type: "function",
|
|
1751
|
+
function: {
|
|
1752
|
+
name: "file_edit",
|
|
1753
|
+
description: "\uD30C\uC77C\uC5D0\uC11C \uD2B9\uC815 \uD14D\uC2A4\uD2B8\uB97C \uCC3E\uC544 \uAD50\uCCB4\uD569\uB2C8\uB2E4.",
|
|
1754
|
+
parameters: {
|
|
1755
|
+
type: "object",
|
|
1756
|
+
properties: {
|
|
1757
|
+
path: { type: "string", description: "\uD30C\uC77C \uACBD\uB85C" },
|
|
1758
|
+
old_text: { type: "string", description: "\uAD50\uCCB4\uD560 \uAE30\uC874 \uD14D\uC2A4\uD2B8" },
|
|
1759
|
+
new_text: { type: "string", description: "\uC0C8 \uD14D\uC2A4\uD2B8" }
|
|
1760
|
+
},
|
|
1761
|
+
required: ["path", "old_text", "new_text"]
|
|
2114
1762
|
}
|
|
2115
|
-
console.log();
|
|
2116
|
-
} else {
|
|
2117
|
-
console.log(chalk12.gray(" \uC5C6\uC74C\n"));
|
|
2118
1763
|
}
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
await guidedProviderSetup();
|
|
2129
|
-
} else if (opts[ci - 1] === "\uAE30\uBCF8 \uBCC0\uACBD") {
|
|
2130
|
-
console.log();
|
|
2131
|
-
providers.forEach((p, i) => console.log(` ${chalk12.cyan(`${i + 1}.`)} ${p.name} (${p.model})`));
|
|
2132
|
-
console.log();
|
|
2133
|
-
const pi = parseInt(await ask(chalk12.cyan(" \u276F "))) - 1;
|
|
2134
|
-
if (pi >= 0 && pi < providers.length) {
|
|
2135
|
-
const { setDefaultProvider: setDefaultProvider2 } = await Promise.resolve().then(() => (init_store(), store_exports));
|
|
2136
|
-
setDefaultProvider2(providers[pi].id);
|
|
2137
|
-
console.log(chalk12.green(` \u2713 \uAE30\uBCF8: ${providers[pi].name}
|
|
2138
|
-
`));
|
|
2139
|
-
}
|
|
2140
|
-
} else if (opts[ci - 1] === "\uC0AD\uC81C") {
|
|
2141
|
-
console.log();
|
|
2142
|
-
providers.forEach((p, i) => console.log(` ${chalk12.cyan(`${i + 1}.`)} ${p.name} (${p.model})`));
|
|
2143
|
-
console.log();
|
|
2144
|
-
const di = parseInt(await ask(chalk12.white(" \uC0AD\uC81C \uBC88\uD638: "))) - 1;
|
|
2145
|
-
if (di >= 0 && di < providers.length) {
|
|
2146
|
-
const { removeProvider: removeProvider2 } = await Promise.resolve().then(() => (init_store(), store_exports));
|
|
2147
|
-
removeProvider2(providers[di].id);
|
|
2148
|
-
console.log(chalk12.green(` \u2713 \uC0AD\uC81C: ${providers[di].name}
|
|
2149
|
-
`));
|
|
1764
|
+
};
|
|
1765
|
+
async function execute3(args) {
|
|
1766
|
+
const path = args.path;
|
|
1767
|
+
const oldText = args.old_text;
|
|
1768
|
+
const newText = args.new_text;
|
|
1769
|
+
try {
|
|
1770
|
+
const content = readFileSync3(path, "utf-8");
|
|
1771
|
+
if (!content.includes(oldText)) {
|
|
1772
|
+
return `Error: \uD14D\uC2A4\uD2B8\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4`;
|
|
2150
1773
|
}
|
|
1774
|
+
const updated = content.replace(oldText, newText);
|
|
1775
|
+
writeFileSync3(path, updated, "utf-8");
|
|
1776
|
+
return `\uD30C\uC77C \uC218\uC815 \uC644\uB8CC: ${path}`;
|
|
1777
|
+
} catch (err) {
|
|
1778
|
+
return `Error: ${err.message}`;
|
|
2151
1779
|
}
|
|
2152
1780
|
}
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
1781
|
+
|
|
1782
|
+
// src/agent/tools/bash.ts
|
|
1783
|
+
var bash_exports = {};
|
|
1784
|
+
__export(bash_exports, {
|
|
1785
|
+
definition: () => definition4,
|
|
1786
|
+
execute: () => execute4
|
|
1787
|
+
});
|
|
1788
|
+
import { execSync } from "child_process";
|
|
1789
|
+
var definition4 = {
|
|
1790
|
+
type: "function",
|
|
1791
|
+
function: {
|
|
1792
|
+
name: "bash",
|
|
1793
|
+
description: "\uC178 \uBA85\uB839\uC5B4\uB97C \uC2E4\uD589\uD569\uB2C8\uB2E4. stdout + stderr\uB97C \uBC18\uD658\uD569\uB2C8\uB2E4.",
|
|
1794
|
+
parameters: {
|
|
1795
|
+
type: "object",
|
|
1796
|
+
properties: {
|
|
1797
|
+
command: { type: "string", description: "\uC2E4\uD589\uD560 \uBA85\uB839\uC5B4" }
|
|
1798
|
+
},
|
|
1799
|
+
required: ["command"]
|
|
2164
1800
|
}
|
|
2165
|
-
console.log();
|
|
2166
|
-
} else {
|
|
2167
|
-
console.log(chalk12.gray(" \uB4F1\uB85D\uB41C \uD658\uACBD \uC5C6\uC74C\n"));
|
|
2168
1801
|
}
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
const name = await ask(chalk12.white(" \uC774\uB984: "));
|
|
2179
|
-
const url = await ask(chalk12.white(" URL: "));
|
|
2180
|
-
const email = await ask(chalk12.white(" \uC774\uBA54\uC77C (\uC120\uD0DD): "));
|
|
2181
|
-
const desc = await ask(chalk12.white(" \uC124\uBA85 (\uC120\uD0DD): "));
|
|
2182
|
-
if (name && url) {
|
|
2183
|
-
const id = name.toLowerCase().replace(/[^a-z0-9]/g, "-");
|
|
2184
|
-
addEnvironment({ id, name, url: url.replace(/\/+$/, ""), email: email || void 0, description: desc || void 0 });
|
|
2185
|
-
console.log(chalk12.green(`
|
|
2186
|
-
\u2713 ${name} \uCD94\uAC00\uB428
|
|
2187
|
-
`));
|
|
2188
|
-
}
|
|
2189
|
-
} else if (ci === 2) {
|
|
2190
|
-
const presets = [
|
|
2191
|
-
{ id: "hq", name: "\uBCF8\uC0AC (244)", url: "https://xgen.x2bee.com", email: "admin@plateer.com", description: "\uBCF8\uC0AC \uBC30\uD3EC \uD658\uACBD" },
|
|
2192
|
-
{ id: "jeju", name: "\uC81C\uC8FC (243)", url: "https://jeju-xgen.x2bee.com", email: "admin@plateer.com", description: "\uC81C\uC8FC \uC11C\uBC84" },
|
|
2193
|
-
{ id: "lotte", name: "\uB86F\uB370\uBAB0 (DGX)", url: "https://lotteimall-xgen.x2bee.com", description: "\uB86F\uB370\uBAB0 DGX Spark" }
|
|
2194
|
-
];
|
|
2195
|
-
console.log(chalk12.bold("\n \uAE30\uBCF8 \uD658\uACBD \uD504\uB9AC\uC14B:\n"));
|
|
2196
|
-
presets.forEach((p, i) => {
|
|
2197
|
-
console.log(` ${chalk12.cyan(`${i + 1}.`)} ${p.name} ${chalk12.gray(p.url)}`);
|
|
2198
|
-
});
|
|
2199
|
-
console.log(` ${chalk12.cyan(`${presets.length + 1}.`)} \uC804\uBD80 \uB4F1\uB85D`);
|
|
2200
|
-
console.log();
|
|
2201
|
-
const pc = await ask(chalk12.cyan(" \u276F "));
|
|
2202
|
-
const pi = parseInt(pc);
|
|
2203
|
-
if (pi === presets.length + 1) {
|
|
2204
|
-
for (const p of presets) addEnvironment(p);
|
|
2205
|
-
console.log(chalk12.green(` \u2713 ${presets.length}\uAC1C \uD658\uACBD \uB4F1\uB85D\uB428
|
|
2206
|
-
`));
|
|
2207
|
-
} else if (pi >= 1 && pi <= presets.length) {
|
|
2208
|
-
addEnvironment(presets[pi - 1]);
|
|
2209
|
-
console.log(chalk12.green(` \u2713 ${presets[pi - 1].name} \uB4F1\uB85D\uB428
|
|
2210
|
-
`));
|
|
2211
|
-
}
|
|
2212
|
-
} else if (opts[ci - 1] === "\uD658\uACBD \uC804\uD658 + \uB85C\uADF8\uC778") {
|
|
2213
|
-
console.log();
|
|
2214
|
-
envs.forEach((e, i) => {
|
|
2215
|
-
const mark = e.id === active?.id ? chalk12.green("\u25CF ") : " ";
|
|
2216
|
-
console.log(` ${mark}${chalk12.cyan(`${i + 1}.`)} ${e.name} ${chalk12.gray(e.url)}`);
|
|
1802
|
+
};
|
|
1803
|
+
async function execute4(args) {
|
|
1804
|
+
const command = args.command;
|
|
1805
|
+
try {
|
|
1806
|
+
const output = execSync(command, {
|
|
1807
|
+
encoding: "utf-8",
|
|
1808
|
+
timeout: 3e4,
|
|
1809
|
+
maxBuffer: 1024 * 1024,
|
|
1810
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
2217
1811
|
});
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
console.log(chalk12.green(`
|
|
2223
|
-
\u2713 ${envs[ei].name} \uC804\uD658\uB428 \u2192 ${envs[ei].url}`));
|
|
2224
|
-
if (envs[ei].email) {
|
|
2225
|
-
const pw = await ask(chalk12.white(` \uBE44\uBC00\uBC88\uD638 (${envs[ei].email}): `));
|
|
2226
|
-
if (pw) {
|
|
2227
|
-
try {
|
|
2228
|
-
const { apiLogin: apiLogin2 } = await Promise.resolve().then(() => (init_auth(), auth_exports));
|
|
2229
|
-
const { setAuth: setAuth2 } = await Promise.resolve().then(() => (init_store(), store_exports));
|
|
2230
|
-
const result = await apiLogin2(envs[ei].email, pw);
|
|
2231
|
-
if (result.success && result.access_token) {
|
|
2232
|
-
setAuth2({ accessToken: result.access_token, refreshToken: result.refresh_token ?? "", userId: result.user_id ?? "", username: result.username ?? "", isAdmin: false, expiresAt: null });
|
|
2233
|
-
console.log(chalk12.green(` \u2713 \uB85C\uADF8\uC778: ${result.username}
|
|
2234
|
-
`));
|
|
2235
|
-
} else {
|
|
2236
|
-
console.log(chalk12.red(` \u2717 ${result.message}
|
|
2237
|
-
`));
|
|
2238
|
-
}
|
|
2239
|
-
} catch (err) {
|
|
2240
|
-
console.log(chalk12.red(` \u2717 ${err.message}
|
|
2241
|
-
`));
|
|
2242
|
-
}
|
|
2243
|
-
}
|
|
2244
|
-
}
|
|
2245
|
-
console.log();
|
|
2246
|
-
}
|
|
2247
|
-
} else if (opts[ci - 1] === "\uC0AD\uC81C") {
|
|
2248
|
-
console.log();
|
|
2249
|
-
envs.forEach((e, i) => console.log(` ${chalk12.cyan(`${i + 1}.`)} ${e.name}`));
|
|
2250
|
-
console.log();
|
|
2251
|
-
const di = parseInt(await ask(chalk12.white(" \uC0AD\uC81C \uBC88\uD638: "))) - 1;
|
|
2252
|
-
if (di >= 0 && di < envs.length) {
|
|
2253
|
-
removeEnvironment(envs[di].id);
|
|
2254
|
-
console.log(chalk12.green(` \u2713 \uC0AD\uC81C: ${envs[di].name}
|
|
2255
|
-
`));
|
|
2256
|
-
}
|
|
1812
|
+
return output || "(no output)";
|
|
1813
|
+
} catch (err) {
|
|
1814
|
+
const e = err;
|
|
1815
|
+
return (e.stdout || "") + (e.stderr || "") || `Error: ${e.message}`;
|
|
2257
1816
|
}
|
|
2258
1817
|
}
|
|
2259
|
-
var init_home = __esm({
|
|
2260
|
-
"src/commands/home.ts"() {
|
|
2261
|
-
"use strict";
|
|
2262
|
-
init_store();
|
|
2263
|
-
init_ui();
|
|
2264
|
-
init_agent();
|
|
2265
|
-
init_chat();
|
|
2266
|
-
init_provider();
|
|
2267
|
-
}
|
|
2268
|
-
});
|
|
2269
1818
|
|
|
2270
|
-
// src/
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
if (mcpManager.serverCount > 0) {
|
|
2291
|
-
const mcpTools = mcpManager.getAllTools();
|
|
2292
|
-
allTools.push(...mcpTools);
|
|
2293
|
-
allToolNames.push(...mcpTools.map((t) => t.function.name));
|
|
2294
|
-
}
|
|
2295
|
-
} catch {
|
|
1819
|
+
// src/agent/tools/grep.ts
|
|
1820
|
+
var grep_exports = {};
|
|
1821
|
+
__export(grep_exports, {
|
|
1822
|
+
definition: () => definition5,
|
|
1823
|
+
execute: () => execute5
|
|
1824
|
+
});
|
|
1825
|
+
import { execSync as execSync2 } from "child_process";
|
|
1826
|
+
var definition5 = {
|
|
1827
|
+
type: "function",
|
|
1828
|
+
function: {
|
|
1829
|
+
name: "grep",
|
|
1830
|
+
description: "\uD30C\uC77C\uC5D0\uC11C \uD328\uD134\uC744 \uAC80\uC0C9\uD569\uB2C8\uB2E4 (\uC7AC\uADC0, \uC904 \uBC88\uD638 \uD3EC\uD568).",
|
|
1831
|
+
parameters: {
|
|
1832
|
+
type: "object",
|
|
1833
|
+
properties: {
|
|
1834
|
+
pattern: { type: "string", description: "\uAC80\uC0C9 \uD328\uD134 (\uC815\uADDC\uC2DD)" },
|
|
1835
|
+
path: { type: "string", description: "\uAC80\uC0C9 \uB514\uB809\uD1A0\uB9AC \uB610\uB294 \uD30C\uC77C (\uAE30\uBCF8: .)" },
|
|
1836
|
+
glob: { type: "string", description: "\uD30C\uC77C \uD544\uD130 (\uC608: *.ts)" }
|
|
1837
|
+
},
|
|
1838
|
+
required: ["pattern"]
|
|
2296
1839
|
}
|
|
2297
1840
|
}
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
process.exit(0);
|
|
2317
|
-
});
|
|
2318
|
-
while (true) {
|
|
2319
|
-
const input = await askUser();
|
|
2320
|
-
if (!input) continue;
|
|
2321
|
-
if (input === "exit" || input === "/exit") {
|
|
2322
|
-
console.log(chalk13.gray("\uC885\uB8CC\uD569\uB2C8\uB2E4."));
|
|
2323
|
-
mcpManager?.stopAll();
|
|
2324
|
-
rl.close();
|
|
2325
|
-
break;
|
|
2326
|
-
}
|
|
2327
|
-
if (input === "/help") {
|
|
2328
|
-
console.log();
|
|
2329
|
-
console.log(chalk13.bold(" \uC2AC\uB798\uC2DC \uCEE4\uB9E8\uB4DC"));
|
|
2330
|
-
console.log(chalk13.gray(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
2331
|
-
console.log(` ${chalk13.cyan("/tools")} \uC0AC\uC6A9 \uAC00\uB2A5\uD55C \uB3C4\uAD6C \uBAA9\uB85D`);
|
|
2332
|
-
console.log(` ${chalk13.cyan("/provider")} \uD604\uC7AC \uD504\uB85C\uBC14\uC774\uB354 \uC815\uBCF4`);
|
|
2333
|
-
console.log(` ${chalk13.cyan("/model")} \uB4F1\uB85D\uB41C \uD504\uB85C\uBC14\uC774\uB354 \uBAA9\uB85D`);
|
|
2334
|
-
console.log(` ${chalk13.cyan("/mcp")} MCP \uC11C\uBC84 \uC0C1\uD0DC`);
|
|
2335
|
-
console.log(` ${chalk13.cyan("/clear")} \uB300\uD654 \uCD08\uAE30\uD654`);
|
|
2336
|
-
console.log(` ${chalk13.cyan("/home")} \uD648 \uBA54\uB274\uB85C \uB3CC\uC544\uAC00\uAE30`);
|
|
2337
|
-
console.log(` ${chalk13.cyan("/exit")} \uC885\uB8CC`);
|
|
2338
|
-
console.log();
|
|
2339
|
-
continue;
|
|
2340
|
-
}
|
|
2341
|
-
if (input === "/clear") {
|
|
2342
|
-
messages.length = 1;
|
|
2343
|
-
console.log(chalk13.gray(" \uB300\uD654 \uCD08\uAE30\uD654\uB428.\n"));
|
|
2344
|
-
continue;
|
|
2345
|
-
}
|
|
2346
|
-
if (input === "/tools") {
|
|
2347
|
-
console.log(chalk13.bold("\n\uB0B4\uC7A5 \uB3C4\uAD6C:"), getToolNames().join(", "));
|
|
2348
|
-
if (mcpManager && mcpManager.serverCount > 0) {
|
|
2349
|
-
console.log(chalk13.bold("MCP \uB3C4\uAD6C:"), mcpManager.getAllTools().map((t) => t.function.name).join(", "));
|
|
2350
|
-
}
|
|
2351
|
-
console.log();
|
|
2352
|
-
continue;
|
|
2353
|
-
}
|
|
2354
|
-
if (input === "/provider") {
|
|
2355
|
-
console.log(chalk13.gray(`\uD604\uC7AC: ${provider.name} (${provider.model})`));
|
|
2356
|
-
console.log(chalk13.gray(`\uBCC0\uACBD: xgen provider add / xgen provider use <id>
|
|
2357
|
-
`));
|
|
2358
|
-
continue;
|
|
2359
|
-
}
|
|
2360
|
-
if (input === "/model") {
|
|
2361
|
-
const { getProviders: gp } = await Promise.resolve().then(() => (init_store(), store_exports));
|
|
2362
|
-
const all = gp();
|
|
2363
|
-
if (all.length > 0) {
|
|
2364
|
-
console.log(chalk13.bold("\n \uB4F1\uB85D\uB41C \uD504\uB85C\uBC14\uC774\uB354:\n"));
|
|
2365
|
-
all.forEach((p, i) => {
|
|
2366
|
-
const mark = p.id === provider.id ? chalk13.green("\u25CF ") : " ";
|
|
2367
|
-
console.log(` ${mark}${i + 1}) ${p.name} (${p.model})`);
|
|
2368
|
-
});
|
|
2369
|
-
console.log(chalk13.gray("\n \uBCC0\uACBD\uD558\uB824\uBA74 exit \uD6C4 xgen provider use <id>\n"));
|
|
2370
|
-
}
|
|
2371
|
-
continue;
|
|
2372
|
-
}
|
|
2373
|
-
if (input === "/home" || input === "/menu") {
|
|
2374
|
-
console.log(chalk13.gray("\uC5D0\uC774\uC804\uD2B8\uB97C \uC885\uB8CC\uD558\uACE0 \uD648\uC73C\uB85C \uB3CC\uC544\uAC11\uB2C8\uB2E4."));
|
|
2375
|
-
mcpManager?.stopAll();
|
|
2376
|
-
rl.close();
|
|
2377
|
-
const { homeMenu: homeMenu2 } = await Promise.resolve().then(() => (init_home(), home_exports));
|
|
2378
|
-
await homeMenu2();
|
|
2379
|
-
return;
|
|
2380
|
-
}
|
|
2381
|
-
if (input === "/mcp") {
|
|
2382
|
-
if (mcpManager && mcpManager.serverCount > 0) {
|
|
2383
|
-
console.log(chalk13.bold("\nMCP \uC11C\uBC84:"), mcpManager.getServerNames().join(", "));
|
|
2384
|
-
console.log(chalk13.gray("\uB3C4\uAD6C:"), mcpManager.getAllTools().map((t) => t.function.name).join(", "));
|
|
2385
|
-
} else {
|
|
2386
|
-
console.log(chalk13.gray("MCP \uC11C\uBC84 \uC5C6\uC74C. .mcp.json\uC744 \uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8\uC5D0 \uCD94\uAC00\uD558\uC138\uC694."));
|
|
2387
|
-
}
|
|
2388
|
-
console.log();
|
|
2389
|
-
continue;
|
|
2390
|
-
}
|
|
2391
|
-
messages.push({ role: "user", content: input });
|
|
2392
|
-
try {
|
|
2393
|
-
await runAgentLoop(client2, provider.model, messages, allTools);
|
|
2394
|
-
} catch (err) {
|
|
2395
|
-
console.log(chalk13.red(`
|
|
2396
|
-
\uC624\uB958: ${err.message}
|
|
2397
|
-
`));
|
|
2398
|
-
}
|
|
1841
|
+
};
|
|
1842
|
+
async function execute5(args) {
|
|
1843
|
+
const pattern = args.pattern;
|
|
1844
|
+
const path = args.path || ".";
|
|
1845
|
+
const glob = args.glob;
|
|
1846
|
+
try {
|
|
1847
|
+
let cmd = `grep -rn --color=never "${pattern.replace(/"/g, '\\"')}" "${path}"`;
|
|
1848
|
+
if (glob) cmd += ` --include="${glob}"`;
|
|
1849
|
+
cmd += " | head -50";
|
|
1850
|
+
const output = execSync2(cmd, {
|
|
1851
|
+
encoding: "utf-8",
|
|
1852
|
+
timeout: 1e4,
|
|
1853
|
+
maxBuffer: 512 * 1024,
|
|
1854
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
1855
|
+
});
|
|
1856
|
+
return output || "\uC77C\uCE58\uD558\uB294 \uACB0\uACFC \uC5C6\uC74C";
|
|
1857
|
+
} catch {
|
|
1858
|
+
return "\uC77C\uCE58\uD558\uB294 \uACB0\uACFC \uC5C6\uC74C";
|
|
2399
1859
|
}
|
|
2400
1860
|
}
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
1861
|
+
|
|
1862
|
+
// src/agent/tools/list-files.ts
|
|
1863
|
+
var list_files_exports = {};
|
|
1864
|
+
__export(list_files_exports, {
|
|
1865
|
+
definition: () => definition6,
|
|
1866
|
+
execute: () => execute6
|
|
1867
|
+
});
|
|
1868
|
+
import { execSync as execSync3 } from "child_process";
|
|
1869
|
+
var definition6 = {
|
|
1870
|
+
type: "function",
|
|
1871
|
+
function: {
|
|
1872
|
+
name: "list_files",
|
|
1873
|
+
description: "\uB514\uB809\uD1A0\uB9AC\uC758 \uD30C\uC77C/\uD3F4\uB354 \uBAA9\uB85D\uC744 \uBC18\uD658\uD569\uB2C8\uB2E4. glob \uD328\uD134 \uC9C0\uC6D0.",
|
|
1874
|
+
parameters: {
|
|
1875
|
+
type: "object",
|
|
1876
|
+
properties: {
|
|
1877
|
+
path: { type: "string", description: "\uB514\uB809\uD1A0\uB9AC \uACBD\uB85C (\uAE30\uBCF8: .)" },
|
|
1878
|
+
pattern: { type: "string", description: "glob \uD328\uD134 (\uC608: **/*.ts)" }
|
|
2418
1879
|
}
|
|
2419
|
-
return;
|
|
2420
1880
|
}
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
try {
|
|
2433
|
-
args = JSON.parse(tc.arguments);
|
|
2434
|
-
} catch {
|
|
2435
|
-
args = {};
|
|
2436
|
-
}
|
|
2437
|
-
console.log(chalk13.gray(` \u2699 `) + chalk13.white.bold(tc.name) + chalk13.gray(` ${summarizeArgs(args)}`));
|
|
2438
|
-
let toolResult;
|
|
2439
|
-
if (mcpManager?.isMcpTool(tc.name)) {
|
|
2440
|
-
toolResult = await mcpManager.callTool(tc.name, args);
|
|
2441
|
-
} else {
|
|
2442
|
-
toolResult = await executeTool(tc.name, args);
|
|
2443
|
-
}
|
|
2444
|
-
const truncated = toolResult.length > 4e3 ? toolResult.slice(0, 4e3) + "\n...(truncated)" : toolResult;
|
|
2445
|
-
messages.push({
|
|
2446
|
-
role: "tool",
|
|
2447
|
-
tool_call_id: tc.id,
|
|
2448
|
-
content: truncated
|
|
2449
|
-
});
|
|
1881
|
+
}
|
|
1882
|
+
};
|
|
1883
|
+
async function execute6(args) {
|
|
1884
|
+
const path = args.path || ".";
|
|
1885
|
+
const pattern = args.pattern;
|
|
1886
|
+
try {
|
|
1887
|
+
let cmd;
|
|
1888
|
+
if (pattern) {
|
|
1889
|
+
cmd = `find "${path}" -name "${pattern}" -type f | head -100`;
|
|
1890
|
+
} else {
|
|
1891
|
+
cmd = `ls -la "${path}"`;
|
|
2450
1892
|
}
|
|
1893
|
+
const output = execSync3(cmd, {
|
|
1894
|
+
encoding: "utf-8",
|
|
1895
|
+
timeout: 1e4,
|
|
1896
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
1897
|
+
});
|
|
1898
|
+
return output || "(empty)";
|
|
1899
|
+
} catch (err) {
|
|
1900
|
+
return `Error: ${err.message}`;
|
|
2451
1901
|
}
|
|
2452
|
-
console.log(chalk13.yellow("\n\uCD5C\uB300 \uBC18\uBCF5 \uD69F\uC218\uC5D0 \uB3C4\uB2EC\uD588\uC2B5\uB2C8\uB2E4.\n"));
|
|
2453
1902
|
}
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
1903
|
+
|
|
1904
|
+
// src/agent/tools/sandbox.ts
|
|
1905
|
+
var sandbox_exports = {};
|
|
1906
|
+
__export(sandbox_exports, {
|
|
1907
|
+
definition: () => definition7,
|
|
1908
|
+
execute: () => execute7
|
|
1909
|
+
});
|
|
1910
|
+
import { execSync as execSync4 } from "child_process";
|
|
1911
|
+
import { mkdirSync as mkdirSync3, writeFileSync as writeFileSync4, existsSync as existsSync2, rmSync } from "fs";
|
|
1912
|
+
import { join as join2 } from "path";
|
|
1913
|
+
import { tmpdir } from "os";
|
|
1914
|
+
var SANDBOX_DIR = join2(tmpdir(), "xgen-sandbox");
|
|
1915
|
+
function ensureSandbox() {
|
|
1916
|
+
if (!existsSync2(SANDBOX_DIR)) {
|
|
1917
|
+
mkdirSync3(SANDBOX_DIR, { recursive: true });
|
|
2459
1918
|
}
|
|
2460
|
-
return
|
|
2461
|
-
}
|
|
2462
|
-
function registerAgentCommand(program2) {
|
|
2463
|
-
program2.command("agent").description("OPEN XGEN AI \uCF54\uB529 \uC5D0\uC774\uC804\uD2B8").action(async () => {
|
|
2464
|
-
await agentRepl();
|
|
2465
|
-
});
|
|
1919
|
+
return SANDBOX_DIR;
|
|
2466
1920
|
}
|
|
2467
|
-
var
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
1921
|
+
var definition7 = {
|
|
1922
|
+
type: "function",
|
|
1923
|
+
function: {
|
|
1924
|
+
name: "sandbox_run",
|
|
1925
|
+
description: "\uACA9\uB9AC\uB41C \uC0CC\uB4DC\uBC15\uC2A4\uC5D0\uC11C \uCF54\uB4DC\uB97C \uC2E4\uD589\uD569\uB2C8\uB2E4. Node.js \uB610\uB294 Python \uCF54\uB4DC\uB97C \uC548\uC804\uD558\uAC8C \uC2E4\uD589\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4. npm \uD328\uD0A4\uC9C0 \uC124\uCE58\uB3C4 \uAC00\uB2A5\uD569\uB2C8\uB2E4.",
|
|
1926
|
+
parameters: {
|
|
1927
|
+
type: "object",
|
|
1928
|
+
properties: {
|
|
1929
|
+
language: {
|
|
1930
|
+
type: "string",
|
|
1931
|
+
enum: ["javascript", "typescript", "python"],
|
|
1932
|
+
description: "\uC2E4\uD589\uD560 \uC5B8\uC5B4"
|
|
1933
|
+
},
|
|
1934
|
+
code: { type: "string", description: "\uC2E4\uD589\uD560 \uCF54\uB4DC" },
|
|
1935
|
+
packages: {
|
|
1936
|
+
type: "array",
|
|
1937
|
+
items: { type: "string" },
|
|
1938
|
+
description: "\uC124\uCE58\uD560 \uD328\uD0A4\uC9C0 (npm \uB610\uB294 pip)"
|
|
1939
|
+
}
|
|
1940
|
+
},
|
|
1941
|
+
required: ["language", "code"]
|
|
1942
|
+
}
|
|
2485
1943
|
}
|
|
2486
|
-
}
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
1944
|
+
};
|
|
1945
|
+
async function execute7(args) {
|
|
1946
|
+
const language = args.language;
|
|
1947
|
+
const code = args.code;
|
|
1948
|
+
const packages = args.packages ?? [];
|
|
1949
|
+
const dir = ensureSandbox();
|
|
1950
|
+
const runId = `run_${Date.now()}`;
|
|
1951
|
+
const runDir = join2(dir, runId);
|
|
1952
|
+
mkdirSync3(runDir, { recursive: true });
|
|
1953
|
+
try {
|
|
1954
|
+
if (packages.length > 0) {
|
|
1955
|
+
if (language === "python") {
|
|
1956
|
+
const pkgList = packages.join(" ");
|
|
1957
|
+
execSync4(`pip install ${pkgList}`, {
|
|
1958
|
+
cwd: runDir,
|
|
1959
|
+
encoding: "utf-8",
|
|
1960
|
+
timeout: 6e4,
|
|
1961
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
1962
|
+
});
|
|
1963
|
+
} else {
|
|
1964
|
+
execSync4("npm init -y", { cwd: runDir, encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] });
|
|
1965
|
+
const pkgList = packages.join(" ");
|
|
1966
|
+
execSync4(`npm install ${pkgList}`, {
|
|
1967
|
+
cwd: runDir,
|
|
1968
|
+
encoding: "utf-8",
|
|
1969
|
+
timeout: 6e4,
|
|
1970
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
1971
|
+
});
|
|
1972
|
+
}
|
|
2503
1973
|
}
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
if (
|
|
2511
|
-
|
|
1974
|
+
let cmd;
|
|
1975
|
+
let filename;
|
|
1976
|
+
if (language === "python") {
|
|
1977
|
+
filename = "script.py";
|
|
1978
|
+
writeFileSync4(join2(runDir, filename), code, "utf-8");
|
|
1979
|
+
cmd = `python3 ${filename}`;
|
|
1980
|
+
} else if (language === "typescript") {
|
|
1981
|
+
filename = "script.ts";
|
|
1982
|
+
writeFileSync4(join2(runDir, filename), code, "utf-8");
|
|
1983
|
+
cmd = `npx tsx ${filename}`;
|
|
2512
1984
|
} else {
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
});
|
|
2517
|
-
config.command("list").description("\uC804\uCCB4 \uC124\uC815 \uD655\uC778").action(() => {
|
|
2518
|
-
const cfg = getConfig();
|
|
2519
|
-
console.log(chalk2.bold("\nXGEN CLI \uC124\uC815"));
|
|
2520
|
-
console.log(chalk2.gray("\u2500".repeat(40)));
|
|
2521
|
-
printKeyValue("\uC11C\uBC84", cfg.server);
|
|
2522
|
-
printKeyValue("\uAE30\uBCF8 \uC6CC\uD06C\uD50C\uB85C\uC6B0", cfg.defaultWorkflow);
|
|
2523
|
-
printKeyValue("\uD14C\uB9C8", cfg.theme);
|
|
2524
|
-
printKeyValue("\uC2A4\uD2B8\uB9BC \uB85C\uADF8", String(cfg.streamLogs));
|
|
2525
|
-
console.log();
|
|
2526
|
-
});
|
|
2527
|
-
config.command("set <key> <value>").description("\uC124\uC815 \uAC12 \uBCC0\uACBD").action((key, value) => {
|
|
2528
|
-
const allowedKeys = ["defaultWorkflow", "theme", "streamLogs"];
|
|
2529
|
-
if (!allowedKeys.includes(key)) {
|
|
2530
|
-
printError(`\uC54C \uC218 \uC5C6\uB294 \uC124\uC815 \uD0A4: ${key}`);
|
|
2531
|
-
console.log(` \uC0AC\uC6A9 \uAC00\uB2A5: ${allowedKeys.join(", ")}`);
|
|
2532
|
-
process.exit(1);
|
|
1985
|
+
filename = "script.mjs";
|
|
1986
|
+
writeFileSync4(join2(runDir, filename), code, "utf-8");
|
|
1987
|
+
cmd = `node ${filename}`;
|
|
2533
1988
|
}
|
|
2534
|
-
const
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
// src/commands/login.ts
|
|
2541
|
-
init_auth();
|
|
2542
|
-
init_store();
|
|
2543
|
-
init_format();
|
|
2544
|
-
import chalk3 from "chalk";
|
|
2545
|
-
import { createInterface } from "readline";
|
|
2546
|
-
function prompt(question, hidden = false) {
|
|
2547
|
-
return new Promise((resolve) => {
|
|
2548
|
-
const rl = createInterface({
|
|
2549
|
-
input: process.stdin,
|
|
2550
|
-
output: process.stdout
|
|
1989
|
+
const output = execSync4(cmd, {
|
|
1990
|
+
cwd: runDir,
|
|
1991
|
+
encoding: "utf-8",
|
|
1992
|
+
timeout: 3e4,
|
|
1993
|
+
maxBuffer: 1024 * 1024,
|
|
1994
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
2551
1995
|
});
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
if (c === "\n" || c === "\r" || c === "") {
|
|
2561
|
-
if (stdin.isTTY) stdin.setRawMode(wasRaw ?? false);
|
|
2562
|
-
stdin.removeListener("data", onData);
|
|
2563
|
-
process.stdout.write("\n");
|
|
2564
|
-
rl.close();
|
|
2565
|
-
resolve(password);
|
|
2566
|
-
} else if (c === "") {
|
|
2567
|
-
process.exit(0);
|
|
2568
|
-
} else if (c === "\x7F" || c === "\b") {
|
|
2569
|
-
if (password.length > 0) {
|
|
2570
|
-
password = password.slice(0, -1);
|
|
2571
|
-
process.stdout.write("\b \b");
|
|
2572
|
-
}
|
|
2573
|
-
} else {
|
|
2574
|
-
password += c;
|
|
2575
|
-
process.stdout.write("*");
|
|
2576
|
-
}
|
|
2577
|
-
};
|
|
2578
|
-
stdin.on("data", onData);
|
|
2579
|
-
} else {
|
|
2580
|
-
rl.question(question, (answer) => {
|
|
2581
|
-
rl.close();
|
|
2582
|
-
resolve(answer.trim());
|
|
2583
|
-
});
|
|
1996
|
+
return output || "(no output)";
|
|
1997
|
+
} catch (err) {
|
|
1998
|
+
const e = err;
|
|
1999
|
+
return (e.stdout || "") + (e.stderr || "") || `Error: ${e.message}`;
|
|
2000
|
+
} finally {
|
|
2001
|
+
try {
|
|
2002
|
+
rmSync(runDir, { recursive: true, force: true });
|
|
2003
|
+
} catch {
|
|
2584
2004
|
}
|
|
2585
|
-
}
|
|
2005
|
+
}
|
|
2586
2006
|
}
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2007
|
+
|
|
2008
|
+
// src/agent/tools/index.ts
|
|
2009
|
+
var tools = [file_read_exports, file_write_exports, file_edit_exports, bash_exports, grep_exports, list_files_exports, sandbox_exports];
|
|
2010
|
+
var toolMap = /* @__PURE__ */ new Map();
|
|
2011
|
+
for (const t of tools) {
|
|
2012
|
+
toolMap.set(t.definition.function.name, t);
|
|
2013
|
+
}
|
|
2014
|
+
function getAllToolDefs() {
|
|
2015
|
+
return tools.map((t) => t.definition);
|
|
2016
|
+
}
|
|
2017
|
+
async function executeTool(name, args) {
|
|
2018
|
+
const tool = toolMap.get(name);
|
|
2019
|
+
if (!tool) return `Unknown tool: ${name}`;
|
|
2020
|
+
return tool.execute(args);
|
|
2021
|
+
}
|
|
2022
|
+
function getToolNames() {
|
|
2023
|
+
return tools.map((t) => t.definition.function.name);
|
|
2024
|
+
}
|
|
2025
|
+
|
|
2026
|
+
// src/agent/tools/xgen-api.ts
|
|
2027
|
+
init_store();
|
|
2028
|
+
var definitions = [
|
|
2029
|
+
{
|
|
2030
|
+
type: "function",
|
|
2031
|
+
function: {
|
|
2032
|
+
name: "xgen_workflow_list",
|
|
2033
|
+
description: "XGEN \uC11C\uBC84\uC5D0\uC11C \uC6CC\uD06C\uD50C\uB85C\uC6B0 \uBAA9\uB85D\uC744 \uAC00\uC838\uC635\uB2C8\uB2E4.",
|
|
2034
|
+
parameters: { type: "object", properties: {} }
|
|
2035
|
+
}
|
|
2036
|
+
},
|
|
2037
|
+
{
|
|
2038
|
+
type: "function",
|
|
2039
|
+
function: {
|
|
2040
|
+
name: "xgen_workflow_run",
|
|
2041
|
+
description: "XGEN \uC6CC\uD06C\uD50C\uB85C\uC6B0\uB97C \uC2E4\uD589\uD569\uB2C8\uB2E4. \uBC30\uD3EC\uB41C \uC6CC\uD06C\uD50C\uB85C\uC6B0\uB9CC \uC2E4\uD589 \uAC00\uB2A5.",
|
|
2042
|
+
parameters: {
|
|
2043
|
+
type: "object",
|
|
2044
|
+
properties: {
|
|
2045
|
+
workflow_id: { type: "string", description: "\uC6CC\uD06C\uD50C\uB85C\uC6B0 ID" },
|
|
2046
|
+
workflow_name: { type: "string", description: "\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uC774\uB984" },
|
|
2047
|
+
input_data: { type: "string", description: "\uC785\uB825 \uBA54\uC2DC\uC9C0" },
|
|
2048
|
+
deploy_key: { type: "string", description: "\uBC30\uD3EC \uD0A4 (\uBC30\uD3EC\uB41C \uC6CC\uD06C\uD50C\uB85C\uC6B0)" }
|
|
2049
|
+
},
|
|
2050
|
+
required: ["workflow_id", "workflow_name", "input_data"]
|
|
2621
2051
|
}
|
|
2622
|
-
} catch (err) {
|
|
2623
|
-
const msg = err?.response?.data?.message ?? err?.response?.data?.detail ?? err.message;
|
|
2624
|
-
printError(`\uB85C\uADF8\uC778 \uC2E4\uD328: ${msg}`);
|
|
2625
|
-
process.exit(1);
|
|
2626
2052
|
}
|
|
2627
|
-
}
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2053
|
+
},
|
|
2054
|
+
{
|
|
2055
|
+
type: "function",
|
|
2056
|
+
function: {
|
|
2057
|
+
name: "xgen_workflow_info",
|
|
2058
|
+
description: "\uD2B9\uC815 \uC6CC\uD06C\uD50C\uB85C\uC6B0\uC758 \uC0C1\uC138 \uC815\uBCF4(\uB178\uB4DC, \uC5E3\uC9C0 \uB4F1)\uB97C \uAC00\uC838\uC635\uB2C8\uB2E4.",
|
|
2059
|
+
parameters: {
|
|
2060
|
+
type: "object",
|
|
2061
|
+
properties: {
|
|
2062
|
+
workflow_id: { type: "string", description: "\uC6CC\uD06C\uD50C\uB85C\uC6B0 ID" }
|
|
2063
|
+
},
|
|
2064
|
+
required: ["workflow_id"]
|
|
2065
|
+
}
|
|
2638
2066
|
}
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
console.log(` ${chalk3.gray("\uC0C1\uD0DC:")} ${chalk3.green("\uD65C\uC131")}`);
|
|
2650
|
-
if (result.is_admin) {
|
|
2651
|
-
console.log(` ${chalk3.gray("\uAD8C\uD55C:")} ${chalk3.yellow("\uAD00\uB9AC\uC790")}`);
|
|
2067
|
+
},
|
|
2068
|
+
{
|
|
2069
|
+
type: "function",
|
|
2070
|
+
function: {
|
|
2071
|
+
name: "xgen_doc_list",
|
|
2072
|
+
description: "XGEN \uC11C\uBC84\uC5D0\uC11C \uBB38\uC11C \uBAA9\uB85D\uC744 \uAC00\uC838\uC635\uB2C8\uB2E4.",
|
|
2073
|
+
parameters: {
|
|
2074
|
+
type: "object",
|
|
2075
|
+
properties: {
|
|
2076
|
+
collection_id: { type: "string", description: "\uCEEC\uB809\uC158 ID (\uC120\uD0DD)" }
|
|
2652
2077
|
}
|
|
2653
|
-
|
|
2654
|
-
|
|
2078
|
+
}
|
|
2079
|
+
}
|
|
2080
|
+
},
|
|
2081
|
+
{
|
|
2082
|
+
type: "function",
|
|
2083
|
+
function: {
|
|
2084
|
+
name: "xgen_ontology_query",
|
|
2085
|
+
description: "\uC628\uD1A8\uB85C\uC9C0(GraphRAG)\uC5D0 \uC9C8\uBB38\uD569\uB2C8\uB2E4. \uC9C0\uC2DD \uADF8\uB798\uD504 \uAE30\uBC18 \uAC80\uC0C9.",
|
|
2086
|
+
parameters: {
|
|
2087
|
+
type: "object",
|
|
2088
|
+
properties: {
|
|
2089
|
+
query: { type: "string", description: "\uC9C8\uC758 \uB0B4\uC6A9" },
|
|
2090
|
+
graph_id: { type: "string", description: "\uADF8\uB798\uD504 ID (\uC120\uD0DD)" }
|
|
2091
|
+
},
|
|
2092
|
+
required: ["query"]
|
|
2093
|
+
}
|
|
2094
|
+
}
|
|
2095
|
+
},
|
|
2096
|
+
{
|
|
2097
|
+
type: "function",
|
|
2098
|
+
function: {
|
|
2099
|
+
name: "xgen_server_status",
|
|
2100
|
+
description: "XGEN \uC11C\uBC84 \uC0C1\uD0DC\uB97C \uD655\uC778\uD569\uB2C8\uB2E4.",
|
|
2101
|
+
parameters: { type: "object", properties: {} }
|
|
2102
|
+
}
|
|
2103
|
+
},
|
|
2104
|
+
{
|
|
2105
|
+
type: "function",
|
|
2106
|
+
function: {
|
|
2107
|
+
name: "xgen_execution_history",
|
|
2108
|
+
description: "\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uC2E4\uD589 \uC774\uB825\uC744 \uAC00\uC838\uC635\uB2C8\uB2E4.",
|
|
2109
|
+
parameters: {
|
|
2110
|
+
type: "object",
|
|
2111
|
+
properties: {
|
|
2112
|
+
limit: { type: "number", description: "\uAC00\uC838\uC62C \uC774\uB825 \uC218 (\uAE30\uBCF8 10)" }
|
|
2655
2113
|
}
|
|
2656
|
-
} else {
|
|
2657
|
-
console.log(` ${chalk3.gray("\uC0C1\uD0DC:")} ${chalk3.red("\uD1A0\uD070 \uB9CC\uB8CC")}`);
|
|
2658
2114
|
}
|
|
2659
|
-
} catch {
|
|
2660
|
-
console.log(` ${chalk3.gray("\uC0C1\uD0DC:")} ${chalk3.yellow("\uAC80\uC99D \uBD88\uAC00 (\uC11C\uBC84 \uC5F0\uACB0 \uC2E4\uD328)")}`);
|
|
2661
2115
|
}
|
|
2662
|
-
|
|
2116
|
+
}
|
|
2117
|
+
];
|
|
2118
|
+
async function execute8(name, args) {
|
|
2119
|
+
const server = getServer();
|
|
2120
|
+
const auth = getAuth();
|
|
2121
|
+
if (!server || !auth) {
|
|
2122
|
+
return "XGEN \uC11C\uBC84\uC5D0 \uC5F0\uACB0\uB418\uC5B4 \uC788\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. /connect \uBA85\uB839\uC73C\uB85C \uC5F0\uACB0\uD558\uC138\uC694.";
|
|
2123
|
+
}
|
|
2124
|
+
try {
|
|
2125
|
+
switch (name) {
|
|
2126
|
+
case "xgen_workflow_list":
|
|
2127
|
+
return await workflowList2();
|
|
2128
|
+
case "xgen_workflow_run":
|
|
2129
|
+
return await workflowRun2(args);
|
|
2130
|
+
case "xgen_workflow_info":
|
|
2131
|
+
return await workflowInfo2(args);
|
|
2132
|
+
case "xgen_doc_list":
|
|
2133
|
+
return await docList(args);
|
|
2134
|
+
case "xgen_ontology_query":
|
|
2135
|
+
return await ontologyQuery(args);
|
|
2136
|
+
case "xgen_server_status":
|
|
2137
|
+
return await serverStatus();
|
|
2138
|
+
case "xgen_execution_history":
|
|
2139
|
+
return await executionHistory(args);
|
|
2140
|
+
default:
|
|
2141
|
+
return `Unknown XGEN tool: ${name}`;
|
|
2142
|
+
}
|
|
2143
|
+
} catch (err) {
|
|
2144
|
+
return `XGEN API \uC624\uB958: ${err.message}`;
|
|
2145
|
+
}
|
|
2146
|
+
}
|
|
2147
|
+
function isXgenTool(name) {
|
|
2148
|
+
return name.startsWith("xgen_");
|
|
2149
|
+
}
|
|
2150
|
+
async function workflowList2() {
|
|
2151
|
+
const { getWorkflowListDetail: getWorkflowListDetail2 } = await Promise.resolve().then(() => (init_workflow(), workflow_exports));
|
|
2152
|
+
const wfs = await getWorkflowListDetail2();
|
|
2153
|
+
if (!wfs.length) return "\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uC5C6\uC74C.";
|
|
2154
|
+
return wfs.map((w, i) => {
|
|
2155
|
+
const deployed = w.is_deployed;
|
|
2156
|
+
const dk = w.deploy_key;
|
|
2157
|
+
const tag = deployed ? " [\uBC30\uD3EC\uB428]" : "";
|
|
2158
|
+
return `${i + 1}. ${w.workflow_name}${tag}
|
|
2159
|
+
ID: ${w.workflow_id ?? w.id}
|
|
2160
|
+
deploy_key: ${dk || "\uC5C6\uC74C"}`;
|
|
2161
|
+
}).join("\n");
|
|
2162
|
+
}
|
|
2163
|
+
async function workflowRun2(args) {
|
|
2164
|
+
const { executeWorkflow: executeWorkflow2 } = await Promise.resolve().then(() => (init_workflow(), workflow_exports));
|
|
2165
|
+
const { randomUUID: randomUUID4 } = await import("crypto");
|
|
2166
|
+
const result = await executeWorkflow2({
|
|
2167
|
+
workflow_id: args.workflow_id,
|
|
2168
|
+
workflow_name: args.workflow_name,
|
|
2169
|
+
input_data: args.input_data,
|
|
2170
|
+
interaction_id: `cli_${randomUUID4().slice(0, 8)}`,
|
|
2171
|
+
deploy_key: args.deploy_key
|
|
2663
2172
|
});
|
|
2173
|
+
if (result.content) return String(result.content);
|
|
2174
|
+
if (result.success === false) return `\uC624\uB958: ${result.error ?? result.message}`;
|
|
2175
|
+
return JSON.stringify(result, null, 2).slice(0, 2e3);
|
|
2176
|
+
}
|
|
2177
|
+
async function workflowInfo2(args) {
|
|
2178
|
+
const { getWorkflowDetail: getWorkflowDetail2 } = await Promise.resolve().then(() => (init_workflow(), workflow_exports));
|
|
2179
|
+
const detail = await getWorkflowDetail2(args.workflow_id);
|
|
2180
|
+
const nodes = detail.nodes?.length ?? 0;
|
|
2181
|
+
const edges = detail.edges?.length ?? 0;
|
|
2182
|
+
return `\uC6CC\uD06C\uD50C\uB85C\uC6B0: ${detail.workflow_name}
|
|
2183
|
+
ID: ${detail.id}
|
|
2184
|
+
\uB178\uB4DC: ${nodes}\uAC1C
|
|
2185
|
+
\uC5E3\uC9C0: ${edges}\uAC1C`;
|
|
2186
|
+
}
|
|
2187
|
+
async function docList(args) {
|
|
2188
|
+
const { listDocuments: listDocuments2 } = await Promise.resolve().then(() => (init_document(), document_exports));
|
|
2189
|
+
const docs = await listDocuments2(args.collection_id);
|
|
2190
|
+
if (!docs.length) return "\uBB38\uC11C \uC5C6\uC74C.";
|
|
2191
|
+
return docs.map(
|
|
2192
|
+
(d, i) => `${i + 1}. ${d.file_name ?? d.name ?? "-"} (${d.file_type ?? "-"}) \u2014 ${d.status ?? "-"}`
|
|
2193
|
+
).join("\n");
|
|
2194
|
+
}
|
|
2195
|
+
async function ontologyQuery(args) {
|
|
2196
|
+
const { queryGraphRAG: queryGraphRAG2 } = await Promise.resolve().then(() => (init_ontology(), ontology_exports));
|
|
2197
|
+
const result = await queryGraphRAG2(args.query, args.graph_id);
|
|
2198
|
+
let output = "";
|
|
2199
|
+
if (result.answer) output += `\uB2F5\uBCC0: ${result.answer}
|
|
2200
|
+
`;
|
|
2201
|
+
if (result.sources?.length) output += `\uCD9C\uCC98: ${result.sources.join(", ")}
|
|
2202
|
+
`;
|
|
2203
|
+
if (result.triples_used?.length) output += `\uD2B8\uB9AC\uD50C: ${result.triples_used.join("; ")}`;
|
|
2204
|
+
return output || "\uACB0\uACFC \uC5C6\uC74C.";
|
|
2205
|
+
}
|
|
2206
|
+
async function serverStatus() {
|
|
2207
|
+
const server = getServer();
|
|
2208
|
+
const auth = getAuth();
|
|
2209
|
+
return `\uC11C\uBC84: ${server}
|
|
2210
|
+
\uC0AC\uC6A9\uC790: ${auth?.username}
|
|
2211
|
+
User ID: ${auth?.userId}`;
|
|
2212
|
+
}
|
|
2213
|
+
async function executionHistory(args) {
|
|
2214
|
+
const { getIOLogs: getIOLogs2 } = await Promise.resolve().then(() => (init_workflow(), workflow_exports));
|
|
2215
|
+
const limit = args.limit || 10;
|
|
2216
|
+
const logs = await getIOLogs2(void 0, limit);
|
|
2217
|
+
if (!logs.length) return "\uC2E4\uD589 \uC774\uB825 \uC5C6\uC74C.";
|
|
2218
|
+
return logs.map(
|
|
2219
|
+
(l, i) => `${i + 1}. [${l.created_at ?? ""}]
|
|
2220
|
+
\uC785\uB825: ${(l.input_data ?? "").slice(0, 80)}
|
|
2221
|
+
\uCD9C\uB825: ${(l.output_data ?? "").slice(0, 80)}`
|
|
2222
|
+
).join("\n");
|
|
2664
2223
|
}
|
|
2665
2224
|
|
|
2666
|
-
// src/
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
import
|
|
2671
|
-
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2225
|
+
// src/mcp/client.ts
|
|
2226
|
+
import { spawn } from "child_process";
|
|
2227
|
+
import { existsSync as existsSync3, readFileSync as readFileSync4 } from "fs";
|
|
2228
|
+
import { join as join3 } from "path";
|
|
2229
|
+
import { createInterface as createInterface4 } from "readline";
|
|
2230
|
+
var McpClient = class {
|
|
2231
|
+
process = null;
|
|
2232
|
+
requestId = 0;
|
|
2233
|
+
pending = /* @__PURE__ */ new Map();
|
|
2234
|
+
serverName;
|
|
2235
|
+
config;
|
|
2236
|
+
tools = [];
|
|
2237
|
+
constructor(serverName, config) {
|
|
2238
|
+
this.serverName = serverName;
|
|
2239
|
+
this.config = config;
|
|
2240
|
+
}
|
|
2241
|
+
async start() {
|
|
2242
|
+
this.process = spawn(this.config.command, this.config.args ?? [], {
|
|
2243
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
2244
|
+
env: { ...process.env, ...this.config.env }
|
|
2245
|
+
});
|
|
2246
|
+
const rl = createInterface4({ input: this.process.stdout });
|
|
2247
|
+
rl.on("line", (line) => {
|
|
2248
|
+
try {
|
|
2249
|
+
const msg = JSON.parse(line);
|
|
2250
|
+
if (msg.id !== void 0 && this.pending.has(msg.id)) {
|
|
2251
|
+
const p = this.pending.get(msg.id);
|
|
2252
|
+
this.pending.delete(msg.id);
|
|
2253
|
+
if (msg.error) {
|
|
2254
|
+
p.reject(new Error(msg.error.message));
|
|
2255
|
+
} else {
|
|
2256
|
+
p.resolve(msg.result);
|
|
2257
|
+
}
|
|
2258
|
+
}
|
|
2259
|
+
} catch {
|
|
2679
2260
|
}
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
const
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2261
|
+
});
|
|
2262
|
+
this.process.on("error", (err) => {
|
|
2263
|
+
console.error(`MCP [${this.serverName}] \uD504\uB85C\uC138\uC2A4 \uC624\uB958:`, err.message);
|
|
2264
|
+
});
|
|
2265
|
+
await this.send("initialize", {
|
|
2266
|
+
protocolVersion: "2024-11-05",
|
|
2267
|
+
capabilities: {},
|
|
2268
|
+
clientInfo: { name: "open-xgen", version: "0.3.0" }
|
|
2269
|
+
});
|
|
2270
|
+
await this.send("notifications/initialized", {});
|
|
2271
|
+
}
|
|
2272
|
+
send(method, params) {
|
|
2273
|
+
return new Promise((resolve, reject) => {
|
|
2274
|
+
const id = ++this.requestId;
|
|
2275
|
+
const request = { jsonrpc: "2.0", id, method, params };
|
|
2276
|
+
this.pending.set(id, { resolve, reject });
|
|
2277
|
+
const timeout = setTimeout(() => {
|
|
2278
|
+
this.pending.delete(id);
|
|
2279
|
+
reject(new Error(`MCP \uC694\uCCAD \uD0C0\uC784\uC544\uC6C3: ${method}`));
|
|
2280
|
+
}, 15e3);
|
|
2281
|
+
this.pending.set(id, {
|
|
2282
|
+
resolve: (v) => {
|
|
2283
|
+
clearTimeout(timeout);
|
|
2284
|
+
resolve(v);
|
|
2285
|
+
},
|
|
2286
|
+
reject: (e) => {
|
|
2287
|
+
clearTimeout(timeout);
|
|
2288
|
+
reject(e);
|
|
2289
|
+
}
|
|
2290
|
+
});
|
|
2291
|
+
this.process?.stdin?.write(JSON.stringify(request) + "\n");
|
|
2292
|
+
});
|
|
2293
|
+
}
|
|
2294
|
+
async listTools() {
|
|
2295
|
+
const result = await this.send("tools/list", {});
|
|
2296
|
+
this.tools = result.tools ?? [];
|
|
2297
|
+
return this.tools;
|
|
2298
|
+
}
|
|
2299
|
+
async callTool(name, args) {
|
|
2300
|
+
const result = await this.send("tools/call", { name, arguments: args });
|
|
2301
|
+
return result.content?.map((c) => c.text ?? "").join("\n") ?? "";
|
|
2302
|
+
}
|
|
2303
|
+
getOpenAITools() {
|
|
2304
|
+
return this.tools.map((t) => ({
|
|
2305
|
+
type: "function",
|
|
2306
|
+
function: {
|
|
2307
|
+
name: `mcp_${this.serverName}_${t.name}`,
|
|
2308
|
+
description: `[MCP:${this.serverName}] ${t.description ?? t.name}`,
|
|
2309
|
+
parameters: t.inputSchema ?? { type: "object", properties: {} }
|
|
2310
|
+
}
|
|
2311
|
+
}));
|
|
2312
|
+
}
|
|
2313
|
+
stop() {
|
|
2314
|
+
this.process?.kill();
|
|
2315
|
+
this.process = null;
|
|
2316
|
+
}
|
|
2317
|
+
};
|
|
2318
|
+
function loadMcpConfig(dir) {
|
|
2319
|
+
const searchPaths = [
|
|
2320
|
+
dir ? join3(dir, ".mcp.json") : null,
|
|
2321
|
+
join3(process.cwd(), ".mcp.json"),
|
|
2322
|
+
join3(process.env.HOME ?? "", ".mcp.json")
|
|
2323
|
+
].filter(Boolean);
|
|
2324
|
+
for (const p of searchPaths) {
|
|
2325
|
+
if (existsSync3(p)) {
|
|
2326
|
+
try {
|
|
2327
|
+
return JSON.parse(readFileSync4(p, "utf-8"));
|
|
2328
|
+
} catch {
|
|
2329
|
+
continue;
|
|
2697
2330
|
}
|
|
2698
|
-
printHeader(`\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uBAA9\uB85D (${workflows.length}\uAC1C)`);
|
|
2699
|
-
console.log();
|
|
2700
|
-
printTable(
|
|
2701
|
-
["#", "ID", "\uC774\uB984"],
|
|
2702
|
-
workflows.map((w, i) => [
|
|
2703
|
-
String(i + 1),
|
|
2704
|
-
(w.workflow_id ?? w.id ?? "-").slice(0, 12),
|
|
2705
|
-
w.workflow_name ?? "-"
|
|
2706
|
-
])
|
|
2707
|
-
);
|
|
2708
2331
|
}
|
|
2709
|
-
console.log();
|
|
2710
|
-
} catch (err) {
|
|
2711
|
-
const msg = err.message;
|
|
2712
|
-
printError(`\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uBAA9\uB85D \uC870\uD68C \uC2E4\uD328: ${msg}`);
|
|
2713
|
-
process.exit(1);
|
|
2714
2332
|
}
|
|
2333
|
+
return null;
|
|
2715
2334
|
}
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
|
|
2728
|
-
printKeyValue("ID", detail.id);
|
|
2729
|
-
printKeyValue("\uC774\uB984", detail.workflow_name);
|
|
2730
|
-
printKeyValue("\uC124\uBA85", detail.description ?? "(\uC5C6\uC74C)");
|
|
2731
|
-
if (detail.nodes && Array.isArray(detail.nodes)) {
|
|
2732
|
-
console.log();
|
|
2733
|
-
console.log(chalk5.bold(" \uB178\uB4DC \uAD6C\uC131:"));
|
|
2734
|
-
for (const node of detail.nodes) {
|
|
2735
|
-
const label = node.data?.label ?? node.id;
|
|
2736
|
-
const type = node.data?.type ?? "unknown";
|
|
2737
|
-
console.log(` ${chalk5.cyan("\u2022")} ${label} ${chalk5.gray(`(${type})`)}`);
|
|
2335
|
+
var McpManager = class {
|
|
2336
|
+
clients = /* @__PURE__ */ new Map();
|
|
2337
|
+
async startAll(config) {
|
|
2338
|
+
for (const [name, serverConfig] of Object.entries(config.mcpServers)) {
|
|
2339
|
+
if (serverConfig.type !== "stdio") continue;
|
|
2340
|
+
try {
|
|
2341
|
+
const client2 = new McpClient(name, serverConfig);
|
|
2342
|
+
await client2.start();
|
|
2343
|
+
await client2.listTools();
|
|
2344
|
+
this.clients.set(name, client2);
|
|
2345
|
+
} catch (err) {
|
|
2346
|
+
console.error(`MCP [${name}] \uC2DC\uC791 \uC2E4\uD328:`, err.message);
|
|
2738
2347
|
}
|
|
2739
2348
|
}
|
|
2740
|
-
|
|
2741
|
-
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
}
|
|
2349
|
+
}
|
|
2350
|
+
getAllTools() {
|
|
2351
|
+
const tools2 = [];
|
|
2352
|
+
for (const client2 of this.clients.values()) {
|
|
2353
|
+
tools2.push(...client2.getOpenAITools());
|
|
2746
2354
|
}
|
|
2747
|
-
|
|
2748
|
-
} catch (err) {
|
|
2749
|
-
const msg = err.message;
|
|
2750
|
-
printError(`\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uC870\uD68C \uC2E4\uD328: ${msg}`);
|
|
2751
|
-
process.exit(1);
|
|
2355
|
+
return tools2;
|
|
2752
2356
|
}
|
|
2753
|
-
|
|
2357
|
+
async callTool(fullName, args) {
|
|
2358
|
+
const parts = fullName.split("_");
|
|
2359
|
+
if (parts.length < 3 || parts[0] !== "mcp") return `Unknown MCP tool: ${fullName}`;
|
|
2360
|
+
const serverName = parts[1];
|
|
2361
|
+
const toolName = parts.slice(2).join("_");
|
|
2362
|
+
const client2 = this.clients.get(serverName);
|
|
2363
|
+
if (!client2) return `MCP \uC11C\uBC84\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${serverName}`;
|
|
2364
|
+
return client2.callTool(toolName, args);
|
|
2365
|
+
}
|
|
2366
|
+
isMcpTool(name) {
|
|
2367
|
+
return name.startsWith("mcp_");
|
|
2368
|
+
}
|
|
2369
|
+
stopAll() {
|
|
2370
|
+
for (const client2 of this.clients.values()) {
|
|
2371
|
+
client2.stop();
|
|
2372
|
+
}
|
|
2373
|
+
this.clients.clear();
|
|
2374
|
+
}
|
|
2375
|
+
get serverCount() {
|
|
2376
|
+
return this.clients.size;
|
|
2377
|
+
}
|
|
2378
|
+
getServerNames() {
|
|
2379
|
+
return [...this.clients.keys()];
|
|
2380
|
+
}
|
|
2381
|
+
};
|
|
2754
2382
|
|
|
2755
|
-
// src/commands/
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
2383
|
+
// src/commands/agent.ts
|
|
2384
|
+
init_provider();
|
|
2385
|
+
init_ui();
|
|
2386
|
+
function buildSystemPrompt() {
|
|
2387
|
+
const server = getServer();
|
|
2388
|
+
const auth = getAuth();
|
|
2389
|
+
const env = getActiveEnvironment();
|
|
2390
|
+
let prompt2 = `You are OPEN XGEN, an AI assistant in the user's terminal.
|
|
2391
|
+
You combine AI coding capabilities with the XGEN workflow platform.
|
|
2762
2392
|
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
var INLINE_CODE_RE = /`([^`]+)`/g;
|
|
2767
|
-
var BOLD_RE = /\*\*(.+?)\*\*/g;
|
|
2768
|
-
var HEADING_RE = /^(#{1,3})\s+(.+)$/gm;
|
|
2769
|
-
var LIST_RE = /^(\s*)[-*]\s+(.+)$/gm;
|
|
2770
|
-
var LINK_RE = /\[([^\]]+)\]\(([^)]+)\)/g;
|
|
2771
|
-
function renderMarkdown(text) {
|
|
2772
|
-
let result = text;
|
|
2773
|
-
result = result.replace(CODE_BLOCK_RE, (_match, lang, code) => {
|
|
2774
|
-
const trimmed = code.trimEnd();
|
|
2775
|
-
const header = lang ? chalk6.gray(` \u2500\u2500 ${lang} \u2500\u2500`) : chalk6.gray(" \u2500\u2500 code \u2500\u2500");
|
|
2776
|
-
const lines = trimmed.split("\n").map((l) => chalk6.white(` ${l}`)).join("\n");
|
|
2777
|
-
return `
|
|
2778
|
-
${header}
|
|
2779
|
-
${lines}
|
|
2780
|
-
${chalk6.gray(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500")}
|
|
2781
|
-
`;
|
|
2782
|
-
});
|
|
2783
|
-
result = result.replace(INLINE_CODE_RE, (_m, code) => chalk6.cyan(`\`${code}\``));
|
|
2784
|
-
result = result.replace(BOLD_RE, (_m, text2) => chalk6.bold(text2));
|
|
2785
|
-
result = result.replace(HEADING_RE, (_m, hashes, text2) => {
|
|
2786
|
-
if (hashes.length === 1) return chalk6.bold.underline(text2);
|
|
2787
|
-
if (hashes.length === 2) return chalk6.bold(text2);
|
|
2788
|
-
return chalk6.bold.dim(text2);
|
|
2789
|
-
});
|
|
2790
|
-
result = result.replace(LIST_RE, (_m, indent, text2) => `${indent}${chalk6.cyan("\u2022")} ${text2}`);
|
|
2791
|
-
result = result.replace(LINK_RE, (_m, label, url) => `${chalk6.blue.underline(label)} ${chalk6.gray(`(${url})`)}`);
|
|
2792
|
-
return result;
|
|
2793
|
-
}
|
|
2393
|
+
## Capabilities
|
|
2394
|
+
1. **Coding**: Read/write files, execute commands, search code, run sandboxed code (JS/TS/Python)
|
|
2395
|
+
2. **XGEN Platform**: List/run workflows, manage documents, query ontology (GraphRAG)
|
|
2794
2396
|
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2397
|
+
## Rules
|
|
2398
|
+
- Respond in the same language as the user
|
|
2399
|
+
- Be concise. Show what you did, not how.
|
|
2400
|
+
- When using tools, briefly describe what you're doing
|
|
2401
|
+
- For XGEN operations, use the xgen_* tools`;
|
|
2402
|
+
if (server && auth) {
|
|
2403
|
+
prompt2 += `
|
|
2404
|
+
|
|
2405
|
+
## XGEN Server Connected
|
|
2406
|
+
- Server: ${server}
|
|
2407
|
+
- User: ${auth.username} (ID: ${auth.userId})
|
|
2408
|
+
- Environment: ${env?.name ?? "default"}
|
|
2409
|
+
You can use xgen_workflow_list, xgen_workflow_run, xgen_doc_list, xgen_ontology_query, etc.`;
|
|
2410
|
+
} else {
|
|
2411
|
+
prompt2 += `
|
|
2412
|
+
|
|
2413
|
+
## XGEN Server: Not connected
|
|
2414
|
+
Tell the user to run /connect to connect to an XGEN server.`;
|
|
2415
|
+
}
|
|
2416
|
+
return prompt2;
|
|
2417
|
+
}
|
|
2418
|
+
var mcpManager = null;
|
|
2419
|
+
async function agentRepl() {
|
|
2420
|
+
let provider = getDefaultProvider();
|
|
2421
|
+
if (!provider) {
|
|
2422
|
+
provider = await guidedProviderSetup();
|
|
2423
|
+
if (!provider) process.exit(1);
|
|
2803
2424
|
}
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
|
|
2814
|
-
} else {
|
|
2815
|
-
printError("\uC785\uB825\uAC12\uC774 \uD544\uC694\uD569\uB2C8\uB2E4. \uC0AC\uC6A9\uBC95:");
|
|
2816
|
-
console.log(' xgen workflow run <id> "\uC785\uB825 \uD14D\uC2A4\uFFFD\uFFFD\uFFFD"');
|
|
2817
|
-
console.log(" xgen workflow run -i <id>");
|
|
2818
|
-
process.exit(1);
|
|
2425
|
+
const client2 = createLLMClient(provider);
|
|
2426
|
+
const allTools = [...getAllToolDefs(), ...definitions];
|
|
2427
|
+
const builtinNames = getToolNames();
|
|
2428
|
+
const mcpConfig = loadMcpConfig();
|
|
2429
|
+
if (mcpConfig && Object.keys(mcpConfig.mcpServers).length > 0) {
|
|
2430
|
+
mcpManager = new McpManager();
|
|
2431
|
+
try {
|
|
2432
|
+
await mcpManager.startAll(mcpConfig);
|
|
2433
|
+
if (mcpManager.serverCount > 0) allTools.push(...mcpManager.getAllTools());
|
|
2434
|
+
} catch {
|
|
2819
2435
|
}
|
|
2820
2436
|
}
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
process.exit(1);
|
|
2824
|
-
}
|
|
2825
|
-
const interactionId = `cli_${randomUUID().slice(0, 8)}`;
|
|
2826
|
-
printHeader(`\uC2E4\uD589: ${workflowName}`);
|
|
2827
|
-
printInfo(`\uC785\uB825: ${input}`);
|
|
2437
|
+
const messages = [{ role: "system", content: buildSystemPrompt() }];
|
|
2438
|
+
console.log(welcome());
|
|
2828
2439
|
console.log();
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
|
|
2833
|
-
|
|
2834
|
-
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
|
|
2838
|
-
await parseSSEStream(
|
|
2839
|
-
stream,
|
|
2840
|
-
(event) => {
|
|
2841
|
-
switch (event.type) {
|
|
2842
|
-
case "token":
|
|
2843
|
-
if (event.content) {
|
|
2844
|
-
if (!hasOutput) {
|
|
2845
|
-
hasOutput = true;
|
|
2846
|
-
console.log();
|
|
2847
|
-
}
|
|
2848
|
-
process.stdout.write(event.content);
|
|
2849
|
-
fullResponse += event.content;
|
|
2850
|
-
}
|
|
2851
|
-
break;
|
|
2852
|
-
case "log":
|
|
2853
|
-
if (opts.logs && event.content) {
|
|
2854
|
-
process.stderr.write(chalk7.gray(`[LOG] ${event.content}
|
|
2855
|
-
`));
|
|
2856
|
-
}
|
|
2857
|
-
break;
|
|
2858
|
-
case "node_status":
|
|
2859
|
-
if (opts.logs) {
|
|
2860
|
-
const nodeName = event.node_name ?? event.node_id ?? "?";
|
|
2861
|
-
const status = event.status ?? "?";
|
|
2862
|
-
process.stderr.write(
|
|
2863
|
-
chalk7.gray(`[\uB178\uB4DC] ${nodeName}: ${status}
|
|
2864
|
-
`)
|
|
2865
|
-
);
|
|
2866
|
-
}
|
|
2867
|
-
break;
|
|
2868
|
-
case "tool":
|
|
2869
|
-
if (opts.logs) {
|
|
2870
|
-
process.stderr.write(chalk7.gray(`[\uB3C4\uAD6C] ${JSON.stringify(event.data)}
|
|
2440
|
+
const server = getServer();
|
|
2441
|
+
const auth = getAuth();
|
|
2442
|
+
const env = getActiveEnvironment();
|
|
2443
|
+
console.log(chalk12.gray(` ${provider.name} \xB7 ${provider.model}`));
|
|
2444
|
+
if (server && auth) {
|
|
2445
|
+
console.log(chalk12.gray(` ${env?.name ?? "XGEN"} \xB7 ${auth.username}@${server.replace("https://", "")}`));
|
|
2446
|
+
}
|
|
2447
|
+
console.log(chalk12.gray(` ${builtinNames.length} \uB3C4\uAD6C + ${definitions.length} XGEN${mcpManager?.serverCount ? ` + ${mcpManager.getAllTools().length} MCP` : ""}`));
|
|
2448
|
+
console.log(chalk12.gray(` /help \xB7 /connect \xB7 /env \xB7 /provider \xB7 /exit
|
|
2871
2449
|
`));
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
|
|
2877
|
-
|
|
2878
|
-
|
|
2879
|
-
|
|
2880
|
-
|
|
2881
|
-
|
|
2882
|
-
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
|
|
2886
|
-
|
|
2887
|
-
|
|
2888
|
-
|
|
2889
|
-
|
|
2890
|
-
(
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
|
|
2901
|
-
|
|
2902
|
-
|
|
2903
|
-
|
|
2450
|
+
const rl = createInterface5({ input: process.stdin, output: process.stdout });
|
|
2451
|
+
const askUser = () => new Promise((resolve) => rl.question(chalk12.cyan(" \u276F "), (a) => resolve(a.trim())));
|
|
2452
|
+
process.on("SIGINT", () => {
|
|
2453
|
+
console.log(chalk12.gray("\n \u{1F44B}\n"));
|
|
2454
|
+
mcpManager?.stopAll();
|
|
2455
|
+
rl.close();
|
|
2456
|
+
process.exit(0);
|
|
2457
|
+
});
|
|
2458
|
+
while (true) {
|
|
2459
|
+
const input = await askUser();
|
|
2460
|
+
if (!input) continue;
|
|
2461
|
+
if (input === "/exit" || input === "exit") {
|
|
2462
|
+
console.log(chalk12.gray("\n \u{1F44B}\n"));
|
|
2463
|
+
mcpManager?.stopAll();
|
|
2464
|
+
rl.close();
|
|
2465
|
+
break;
|
|
2466
|
+
}
|
|
2467
|
+
if (input === "/help") {
|
|
2468
|
+
console.log(`
|
|
2469
|
+
${chalk12.bold("\uC2AC\uB798\uC2DC \uCEE4\uB9E8\uB4DC")}
|
|
2470
|
+
${chalk12.cyan("/connect")} XGEN \uC11C\uBC84 \uC5F0\uACB0 + \uB85C\uADF8\uC778
|
|
2471
|
+
${chalk12.cyan("/env")} \uD658\uACBD \uC804\uD658 (\uBCF8\uC0AC/\uC81C\uC8FC/\uB86F\uB370\uBAB0)
|
|
2472
|
+
${chalk12.cyan("/provider")} \uD504\uB85C\uBC14\uC774\uB354 \uBCC0\uACBD
|
|
2473
|
+
${chalk12.cyan("/tools")} \uC0AC\uC6A9 \uAC00\uB2A5\uD55C \uB3C4\uAD6C \uBAA9\uB85D
|
|
2474
|
+
${chalk12.cyan("/status")} \uD604\uC7AC \uC5F0\uACB0 \uC0C1\uD0DC
|
|
2475
|
+
${chalk12.cyan("/clear")} \uB300\uD654 \uCD08\uAE30\uD654
|
|
2476
|
+
${chalk12.cyan("/exit")} \uC885\uB8CC
|
|
2477
|
+
`);
|
|
2478
|
+
continue;
|
|
2479
|
+
}
|
|
2480
|
+
if (input === "/clear") {
|
|
2481
|
+
messages.length = 0;
|
|
2482
|
+
messages.push({ role: "system", content: buildSystemPrompt() });
|
|
2483
|
+
console.log(chalk12.gray(" \uB300\uD654 \uCD08\uAE30\uD654\uB428.\n"));
|
|
2484
|
+
continue;
|
|
2485
|
+
}
|
|
2486
|
+
if (input === "/status") {
|
|
2487
|
+
const p = getDefaultProvider();
|
|
2488
|
+
const s = getServer();
|
|
2489
|
+
const a = getAuth();
|
|
2490
|
+
const e = getActiveEnvironment();
|
|
2491
|
+
console.log();
|
|
2492
|
+
console.log(` ${chalk12.bold("\uD504\uB85C\uBC14\uC774\uB354")} ${p ? `${p.name} \xB7 ${p.model}` : chalk12.red("\uBBF8\uC124\uC815")}`);
|
|
2493
|
+
console.log(` ${chalk12.bold("\uC11C\uBC84")} ${s && a ? `${a.username}@${s.replace("https://", "")}` : chalk12.red("\uBBF8\uC5F0\uACB0")}`);
|
|
2494
|
+
console.log(` ${chalk12.bold("\uD658\uACBD")} ${e?.name ?? "\uC5C6\uC74C"} (${getEnvironments().length}\uAC1C \uB4F1\uB85D)`);
|
|
2495
|
+
if (mcpManager?.serverCount) {
|
|
2496
|
+
console.log(` ${chalk12.bold("MCP")} ${mcpManager.getServerNames().join(", ")}`);
|
|
2904
2497
|
}
|
|
2905
|
-
|
|
2906
|
-
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
2498
|
+
console.log();
|
|
2499
|
+
continue;
|
|
2500
|
+
}
|
|
2501
|
+
if (input === "/tools") {
|
|
2502
|
+
console.log(`
|
|
2503
|
+
${chalk12.bold("\uCF54\uB529")} ${builtinNames.join(", ")}`);
|
|
2504
|
+
console.log(` ${chalk12.bold("XGEN")} ${definitions.map((t) => t.function.name).join(", ")}`);
|
|
2505
|
+
if (mcpManager?.serverCount) {
|
|
2506
|
+
console.log(` ${chalk12.bold("MCP")} ${mcpManager.getAllTools().map((t) => t.function.name).join(", ")}`);
|
|
2507
|
+
}
|
|
2508
|
+
console.log();
|
|
2509
|
+
continue;
|
|
2510
|
+
}
|
|
2511
|
+
if (input === "/connect") {
|
|
2512
|
+
await connectServer();
|
|
2513
|
+
messages[0] = { role: "system", content: buildSystemPrompt() };
|
|
2514
|
+
continue;
|
|
2515
|
+
}
|
|
2516
|
+
if (input === "/env") {
|
|
2517
|
+
await switchEnv();
|
|
2518
|
+
messages[0] = { role: "system", content: buildSystemPrompt() };
|
|
2519
|
+
continue;
|
|
2520
|
+
}
|
|
2521
|
+
if (input === "/provider") {
|
|
2522
|
+
const { guidedProviderSetup: setup } = await Promise.resolve().then(() => (init_provider(), provider_exports));
|
|
2523
|
+
await setup();
|
|
2524
|
+
console.log(chalk12.gray(" \uD504\uB85C\uBC14\uC774\uB354 \uBCC0\uACBD\uB428. /exit \uD6C4 \uC7AC\uC2DC\uC791\uD558\uC138\uC694.\n"));
|
|
2525
|
+
continue;
|
|
2526
|
+
}
|
|
2527
|
+
messages.push({ role: "user", content: input });
|
|
2528
|
+
try {
|
|
2529
|
+
await runLoop(client2, provider.model, messages, allTools);
|
|
2530
|
+
} catch (err) {
|
|
2531
|
+
console.log(chalk12.red(`
|
|
2532
|
+
\uC624\uB958: ${err.message}
|
|
2533
|
+
`));
|
|
2534
|
+
}
|
|
2910
2535
|
}
|
|
2911
2536
|
}
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
if (
|
|
2924
|
-
|
|
2537
|
+
async function runLoop(client2, model, messages, tools2) {
|
|
2538
|
+
for (let i = 0; i < 20; i++) {
|
|
2539
|
+
let first = true;
|
|
2540
|
+
const result = await streamChat(client2, model, messages, tools2, (delta) => {
|
|
2541
|
+
if (first) {
|
|
2542
|
+
process.stdout.write(chalk12.green("\n ") + "");
|
|
2543
|
+
first = false;
|
|
2544
|
+
}
|
|
2545
|
+
process.stdout.write(delta);
|
|
2546
|
+
});
|
|
2547
|
+
if (result.content) process.stdout.write("\n\n");
|
|
2548
|
+
if (result.toolCalls.length === 0) {
|
|
2549
|
+
if (result.content) messages.push({ role: "assistant", content: result.content });
|
|
2925
2550
|
return;
|
|
2926
2551
|
}
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
|
|
2940
|
-
|
|
2552
|
+
messages.push({
|
|
2553
|
+
role: "assistant",
|
|
2554
|
+
content: result.content || null,
|
|
2555
|
+
tool_calls: result.toolCalls.map((tc) => ({
|
|
2556
|
+
id: tc.id,
|
|
2557
|
+
type: "function",
|
|
2558
|
+
function: { name: tc.name, arguments: tc.arguments }
|
|
2559
|
+
}))
|
|
2560
|
+
});
|
|
2561
|
+
for (const tc of result.toolCalls) {
|
|
2562
|
+
let args;
|
|
2563
|
+
try {
|
|
2564
|
+
args = JSON.parse(tc.arguments);
|
|
2565
|
+
} catch {
|
|
2566
|
+
args = {};
|
|
2941
2567
|
}
|
|
2942
|
-
|
|
2568
|
+
const shortArgs = Object.entries(args).map(([k, v]) => {
|
|
2569
|
+
const s = String(v);
|
|
2570
|
+
return `${k}=${s.length > 30 ? s.slice(0, 30) + "\u2026" : s}`;
|
|
2571
|
+
}).join(" ");
|
|
2572
|
+
console.log(chalk12.gray(` \u2699 ${chalk12.white(tc.name)} ${shortArgs}`));
|
|
2573
|
+
let toolResult;
|
|
2574
|
+
if (isXgenTool(tc.name)) {
|
|
2575
|
+
toolResult = await execute8(tc.name, args);
|
|
2576
|
+
} else if (mcpManager?.isMcpTool(tc.name)) {
|
|
2577
|
+
toolResult = await mcpManager.callTool(tc.name, args);
|
|
2578
|
+
} else {
|
|
2579
|
+
toolResult = await executeTool(tc.name, args);
|
|
2580
|
+
}
|
|
2581
|
+
const truncated = toolResult.length > 4e3 ? toolResult.slice(0, 4e3) + "\n\u2026(truncated)" : toolResult;
|
|
2582
|
+
messages.push({ role: "tool", tool_call_id: tc.id, content: truncated });
|
|
2583
|
+
}
|
|
2584
|
+
}
|
|
2585
|
+
console.log(chalk12.yellow("\n \uCD5C\uB300 \uBC18\uBCF5 \uD69F\uC218 \uB3C4\uB2EC.\n"));
|
|
2586
|
+
}
|
|
2587
|
+
async function connectServer() {
|
|
2588
|
+
const { setServer: setServer2, setAuth: setAuth2 } = await Promise.resolve().then(() => (init_store(), store_exports));
|
|
2589
|
+
const { addEnvironment: addEnvironment2 } = await Promise.resolve().then(() => (init_store(), store_exports));
|
|
2590
|
+
console.log(chalk12.bold("\n XGEN \uC11C\uBC84 \uC5F0\uACB0\n"));
|
|
2591
|
+
const presets = [
|
|
2592
|
+
{ id: "hq", name: "\uBCF8\uC0AC", url: "https://xgen.x2bee.com", email: "admin@plateer.com" },
|
|
2593
|
+
{ id: "jeju", name: "\uC81C\uC8FC", url: "https://jeju-xgen.x2bee.com", email: "admin@plateer.com" },
|
|
2594
|
+
{ id: "lotte", name: "\uB86F\uB370\uBAB0", url: "https://lotteimall-xgen.x2bee.com" }
|
|
2595
|
+
];
|
|
2596
|
+
presets.forEach((p, i) => console.log(` ${chalk12.cyan(`${i + 1}.`)} ${p.name} ${chalk12.gray(p.url)}`));
|
|
2597
|
+
console.log(` ${chalk12.cyan("4.")} \uC9C1\uC811 \uC785\uB825`);
|
|
2598
|
+
console.log();
|
|
2599
|
+
const choice = await ask(chalk12.cyan(" \u276F "));
|
|
2600
|
+
let url;
|
|
2601
|
+
let email;
|
|
2602
|
+
const ci = parseInt(choice) - 1;
|
|
2603
|
+
if (ci >= 0 && ci < presets.length) {
|
|
2604
|
+
url = presets[ci].url;
|
|
2605
|
+
email = presets[ci].email;
|
|
2606
|
+
addEnvironment2({ ...presets[ci], description: presets[ci].name });
|
|
2607
|
+
} else {
|
|
2608
|
+
url = await ask(chalk12.white(" URL: "));
|
|
2609
|
+
if (!url) return;
|
|
2610
|
+
}
|
|
2611
|
+
setServer2(url);
|
|
2612
|
+
console.log(chalk12.green(` \u2713 ${url}
|
|
2613
|
+
`));
|
|
2614
|
+
const inputEmail = email || await ask(chalk12.white(" \uC774\uBA54\uC77C: "));
|
|
2615
|
+
const pw = await ask(chalk12.white(" \uBE44\uBC00\uBC88\uD638: "));
|
|
2616
|
+
if (!inputEmail || !pw) return;
|
|
2617
|
+
try {
|
|
2618
|
+
const { apiLogin: apiLogin2 } = await Promise.resolve().then(() => (init_auth(), auth_exports));
|
|
2619
|
+
const result = await apiLogin2(inputEmail, pw);
|
|
2620
|
+
if (result.success && result.access_token) {
|
|
2621
|
+
setAuth2({ accessToken: result.access_token, refreshToken: result.refresh_token ?? "", userId: result.user_id ?? "", username: result.username ?? "", isAdmin: false, expiresAt: null });
|
|
2622
|
+
console.log(chalk12.green(` \u2713 ${result.username} \uB85C\uADF8\uC778\uB428
|
|
2623
|
+
`));
|
|
2624
|
+
} else {
|
|
2625
|
+
console.log(chalk12.red(` \u2717 ${result.message}
|
|
2626
|
+
`));
|
|
2943
2627
|
}
|
|
2944
2628
|
} catch (err) {
|
|
2945
|
-
|
|
2946
|
-
|
|
2947
|
-
process.exit(1);
|
|
2629
|
+
console.log(chalk12.red(` \u2717 ${err.message}
|
|
2630
|
+
`));
|
|
2948
2631
|
}
|
|
2949
2632
|
}
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
|
|
2955
|
-
|
|
2956
|
-
|
|
2957
|
-
|
|
2633
|
+
async function switchEnv() {
|
|
2634
|
+
const { getEnvironments: getEnvs, switchEnvironment: switchEnvironment2 } = await Promise.resolve().then(() => (init_store(), store_exports));
|
|
2635
|
+
const envs = getEnvs();
|
|
2636
|
+
if (!envs.length) {
|
|
2637
|
+
console.log(chalk12.gray("\n \uD658\uACBD \uC5C6\uC74C. /connect\uB85C \uBA3C\uC800 \uC5F0\uACB0\uD558\uC138\uC694.\n"));
|
|
2638
|
+
return;
|
|
2639
|
+
}
|
|
2640
|
+
const active = getActiveEnvironment();
|
|
2641
|
+
console.log();
|
|
2642
|
+
envs.forEach((e, i) => {
|
|
2643
|
+
const mark = e.id === active?.id ? chalk12.green("\u25CF ") : " ";
|
|
2644
|
+
console.log(` ${mark}${chalk12.cyan(`${i + 1}.`)} ${e.name} ${chalk12.gray(e.url)}`);
|
|
2645
|
+
});
|
|
2646
|
+
console.log();
|
|
2647
|
+
const ci = parseInt(await ask(chalk12.cyan(" \u276F "))) - 1;
|
|
2648
|
+
if (ci >= 0 && ci < envs.length) {
|
|
2649
|
+
switchEnvironment2(envs[ci].id);
|
|
2650
|
+
console.log(chalk12.green(` \u2713 ${envs[ci].name}
|
|
2651
|
+
`));
|
|
2652
|
+
}
|
|
2653
|
+
}
|
|
2654
|
+
function registerAgentCommand(program2) {
|
|
2655
|
+
program2.command("agent").description("OPEN XGEN AI \uC5D0\uC774\uC804\uD2B8").action(async () => {
|
|
2656
|
+
await agentRepl();
|
|
2657
|
+
});
|
|
2958
2658
|
}
|
|
2959
|
-
|
|
2960
|
-
// src/index.ts
|
|
2961
|
-
init_chat();
|
|
2962
|
-
init_provider();
|
|
2963
|
-
init_agent();
|
|
2964
2659
|
|
|
2965
2660
|
// src/commands/doc.ts
|
|
2966
2661
|
init_store();
|
|
2967
2662
|
init_document();
|
|
2968
2663
|
init_format();
|
|
2969
|
-
import
|
|
2664
|
+
import chalk13 from "chalk";
|
|
2970
2665
|
function registerDocCommand(program2) {
|
|
2971
2666
|
const doc = program2.command("doc").description("\uBB38\uC11C \uAD00\uB9AC");
|
|
2972
2667
|
doc.command("list").alias("ls").description("\uBB38\uC11C \uBAA9\uB85D \uC870\uD68C").option("-c, --collection <id>", "\uCEEC\uB809\uC158 ID").action(async (opts) => {
|
|
@@ -2974,7 +2669,7 @@ function registerDocCommand(program2) {
|
|
|
2974
2669
|
try {
|
|
2975
2670
|
const docs = await listDocuments(opts.collection);
|
|
2976
2671
|
if (!docs.length) {
|
|
2977
|
-
console.log(
|
|
2672
|
+
console.log(chalk13.yellow("\n\uBB38\uC11C\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.\n"));
|
|
2978
2673
|
return;
|
|
2979
2674
|
}
|
|
2980
2675
|
printHeader(`\uBB38\uC11C \uBAA9\uB85D (${docs.length}\uAC1C)`);
|
|
@@ -2998,10 +2693,10 @@ function registerDocCommand(program2) {
|
|
|
2998
2693
|
doc.command("upload <file>").description("\uBB38\uC11C \uC5C5\uB85C\uB4DC").option("-c, --collection <id>", "\uCEEC\uB809\uC158 ID").option("-n, --name <name>", "\uD30C\uC77C\uBA85").action(async (file, opts) => {
|
|
2999
2694
|
requireAuth();
|
|
3000
2695
|
try {
|
|
3001
|
-
console.log(
|
|
2696
|
+
console.log(chalk13.gray(`\uC5C5\uB85C\uB4DC \uC911: ${file}`));
|
|
3002
2697
|
const result = await uploadDocument(file, opts.collection, opts.name);
|
|
3003
|
-
console.log(
|
|
3004
|
-
console.log(
|
|
2698
|
+
console.log(chalk13.green("\u2713 \uC5C5\uB85C\uB4DC \uC644\uB8CC"));
|
|
2699
|
+
console.log(chalk13.gray(JSON.stringify(result, null, 2)));
|
|
3005
2700
|
} catch (err) {
|
|
3006
2701
|
printError(`\uC5C5\uB85C\uB4DC \uC2E4\uD328: ${err.message}`);
|
|
3007
2702
|
}
|
|
@@ -3011,7 +2706,7 @@ function registerDocCommand(program2) {
|
|
|
3011
2706
|
try {
|
|
3012
2707
|
const d = await getDocumentInfo(id);
|
|
3013
2708
|
printHeader("\uBB38\uC11C \uC815\uBCF4");
|
|
3014
|
-
console.log(
|
|
2709
|
+
console.log(chalk13.gray(JSON.stringify(d, null, 2)));
|
|
3015
2710
|
} catch (err) {
|
|
3016
2711
|
printError(`\uC870\uD68C \uC2E4\uD328: ${err.message}`);
|
|
3017
2712
|
}
|
|
@@ -3022,7 +2717,7 @@ function registerDocCommand(program2) {
|
|
|
3022
2717
|
init_store();
|
|
3023
2718
|
init_ontology();
|
|
3024
2719
|
init_format();
|
|
3025
|
-
import
|
|
2720
|
+
import chalk14 from "chalk";
|
|
3026
2721
|
import { createInterface as createInterface6 } from "readline";
|
|
3027
2722
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
3028
2723
|
function registerOntologyCommand(program2) {
|
|
@@ -3030,19 +2725,19 @@ function registerOntologyCommand(program2) {
|
|
|
3030
2725
|
ont.command("query <question>").alias("q").description("GraphRAG \uC6D0\uC0F7 \uC9C8\uC758").option("-g, --graph <id>", "\uADF8\uB798\uD504 ID").option("--no-scs", "SCS \uCEE8\uD14D\uC2A4\uD2B8 \uBE44\uD65C\uC131\uD654").action(async (question, opts) => {
|
|
3031
2726
|
requireAuth();
|
|
3032
2727
|
try {
|
|
3033
|
-
console.log(
|
|
2728
|
+
console.log(chalk14.gray("\n\uC9C8\uC758 \uC911...\n"));
|
|
3034
2729
|
const result = await queryGraphRAG(question, opts.graph, { scs: opts.scs });
|
|
3035
2730
|
if (result.answer) {
|
|
3036
|
-
console.log(
|
|
2731
|
+
console.log(chalk14.bold("\uB2F5\uBCC0:"));
|
|
3037
2732
|
console.log(result.answer);
|
|
3038
2733
|
}
|
|
3039
2734
|
if (result.sources?.length) {
|
|
3040
|
-
console.log(
|
|
3041
|
-
result.sources.forEach((s) => console.log(
|
|
2735
|
+
console.log(chalk14.bold("\n\uCD9C\uCC98:"));
|
|
2736
|
+
result.sources.forEach((s) => console.log(chalk14.gray(` - ${s}`)));
|
|
3042
2737
|
}
|
|
3043
2738
|
if (result.triples_used?.length) {
|
|
3044
|
-
console.log(
|
|
3045
|
-
result.triples_used.forEach((t) => console.log(
|
|
2739
|
+
console.log(chalk14.bold("\n\uC0AC\uC6A9\uB41C \uD2B8\uB9AC\uD50C:"));
|
|
2740
|
+
result.triples_used.forEach((t) => console.log(chalk14.dim(` ${t}`)));
|
|
3046
2741
|
}
|
|
3047
2742
|
console.log();
|
|
3048
2743
|
} catch (err) {
|
|
@@ -3053,9 +2748,9 @@ function registerOntologyCommand(program2) {
|
|
|
3053
2748
|
requireAuth();
|
|
3054
2749
|
const sessionId = randomUUID3();
|
|
3055
2750
|
printHeader("Ontology Chat");
|
|
3056
|
-
console.log(
|
|
2751
|
+
console.log(chalk14.gray("\uBA40\uD2F0\uD134 GraphRAG \uB300\uD654. exit\uB85C \uC885\uB8CC.\n"));
|
|
3057
2752
|
const rl = createInterface6({ input: process.stdin, output: process.stdout });
|
|
3058
|
-
const ask2 = () => new Promise((resolve) => rl.question(
|
|
2753
|
+
const ask2 = () => new Promise((resolve) => rl.question(chalk14.green("\u276F "), (a) => resolve(a.trim())));
|
|
3059
2754
|
while (true) {
|
|
3060
2755
|
const input = await ask2();
|
|
3061
2756
|
if (!input) continue;
|
|
@@ -3069,7 +2764,7 @@ function registerOntologyCommand(program2) {
|
|
|
3069
2764
|
${result.answer}
|
|
3070
2765
|
`);
|
|
3071
2766
|
} catch (err) {
|
|
3072
|
-
console.log(
|
|
2767
|
+
console.log(chalk14.red(`\uC624\uB958: ${err.message}
|
|
3073
2768
|
`));
|
|
3074
2769
|
}
|
|
3075
2770
|
}
|
|
@@ -3079,7 +2774,7 @@ ${result.answer}
|
|
|
3079
2774
|
try {
|
|
3080
2775
|
const stats = await getGraphStats(graphId);
|
|
3081
2776
|
printHeader("\uADF8\uB798\uD504 \uD1B5\uACC4");
|
|
3082
|
-
console.log(
|
|
2777
|
+
console.log(chalk14.gray(JSON.stringify(stats, null, 2)));
|
|
3083
2778
|
console.log();
|
|
3084
2779
|
} catch (err) {
|
|
3085
2780
|
printError(`\uD1B5\uACC4 \uC870\uD68C \uC2E4\uD328: ${err.message}`);
|
|
@@ -3088,44 +2783,43 @@ ${result.answer}
|
|
|
3088
2783
|
}
|
|
3089
2784
|
|
|
3090
2785
|
// src/index.ts
|
|
3091
|
-
init_home();
|
|
3092
2786
|
var VERSION = "0.3.0";
|
|
3093
|
-
var LOGO =
|
|
2787
|
+
var LOGO = chalk15.cyan(`
|
|
3094
2788
|
\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588 \u2588\u2588
|
|
3095
2789
|
\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588 \u2588\u2588
|
|
3096
2790
|
\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588
|
|
3097
2791
|
\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588
|
|
3098
2792
|
\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588
|
|
3099
|
-
`) +
|
|
2793
|
+
`) + chalk15.white.bold(`
|
|
3100
2794
|
\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588 \u2588\u2588
|
|
3101
2795
|
\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588 \u2588\u2588
|
|
3102
2796
|
\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588
|
|
3103
2797
|
\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588
|
|
3104
2798
|
\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588
|
|
3105
|
-
`) +
|
|
2799
|
+
`) + chalk15.gray(` v${VERSION}
|
|
3106
2800
|
`);
|
|
3107
2801
|
var BANNER = LOGO;
|
|
3108
2802
|
var program = new Command();
|
|
3109
2803
|
program.name("xgen").description("OPEN XGEN \u2014 AI Coding Agent + XGEN Platform CLI").version(VERSION).addHelpText("before", BANNER).addHelpText(
|
|
3110
2804
|
"after",
|
|
3111
2805
|
`
|
|
3112
|
-
${
|
|
3113
|
-
${
|
|
3114
|
-
${
|
|
3115
|
-
${
|
|
3116
|
-
${
|
|
2806
|
+
${chalk15.bold("\uC2DC\uC791\uD558\uAE30:")}
|
|
2807
|
+
${chalk15.cyan("xgen provider add")} AI \uD504\uB85C\uBC14\uC774\uB354 \uC124\uC815
|
|
2808
|
+
${chalk15.cyan("xgen agent")} AI \uCF54\uB529 \uC5D0\uC774\uC804\uD2B8
|
|
2809
|
+
${chalk15.cyan("xgen config set-server")} <url> XGEN \uC11C\uBC84 \uC5F0\uACB0
|
|
2810
|
+
${chalk15.cyan("xgen login")} \uC11C\uBC84 \uB85C\uADF8\uC778
|
|
3117
2811
|
|
|
3118
|
-
${
|
|
3119
|
-
${
|
|
3120
|
-
${
|
|
3121
|
-
${
|
|
2812
|
+
${chalk15.bold("AI \uC5D0\uC774\uC804\uD2B8:")}
|
|
2813
|
+
${chalk15.cyan("xgen agent")} \uCF54\uB529 \uC5D0\uC774\uC804\uD2B8 (\uD30C\uC77C, \uD130\uBBF8\uB110, \uAC80\uC0C9)
|
|
2814
|
+
${chalk15.cyan("xgen provider ls")} \uD504\uB85C\uBC14\uC774\uB354 \uBAA9\uB85D
|
|
2815
|
+
${chalk15.cyan("xgen provider add")} \uD504\uB85C\uBC14\uC774\uB354 \uCD94\uAC00
|
|
3122
2816
|
|
|
3123
|
-
${
|
|
3124
|
-
${
|
|
3125
|
-
${
|
|
3126
|
-
${
|
|
3127
|
-
${
|
|
3128
|
-
${
|
|
2817
|
+
${chalk15.bold("XGEN \uD50C\uB7AB\uD3FC:")}
|
|
2818
|
+
${chalk15.cyan("xgen chat")} \uC6CC\uD06C\uD50C\uB85C\uC6B0 \uB300\uD654
|
|
2819
|
+
${chalk15.cyan("xgen wf ls")} \uC6CC\uD06C\uD50C\uB85C\uC6B0 \uBAA9\uB85D
|
|
2820
|
+
${chalk15.cyan("xgen wf run")} <id> "\uC9C8\uBB38" \uC6CC\uD06C\uD50C\uB85C\uC6B0 \uC2E4\uD589
|
|
2821
|
+
${chalk15.cyan("xgen doc ls")} \uBB38\uC11C \uBAA9\uB85D
|
|
2822
|
+
${chalk15.cyan("xgen ont query")} "\uC9C8\uBB38" \uC628\uD1A8\uB85C\uC9C0 \uC9C8\uC758
|
|
3129
2823
|
`
|
|
3130
2824
|
);
|
|
3131
2825
|
registerConfigCommand(program);
|
|
@@ -3137,8 +2831,8 @@ registerAgentCommand(program);
|
|
|
3137
2831
|
registerDocCommand(program);
|
|
3138
2832
|
registerOntologyCommand(program);
|
|
3139
2833
|
if (process.argv.length <= 2) {
|
|
3140
|
-
|
|
3141
|
-
console.error(
|
|
2834
|
+
agentRepl().catch((err) => {
|
|
2835
|
+
console.error(chalk15.red(`\uC624\uB958: ${err.message}`));
|
|
3142
2836
|
process.exit(1);
|
|
3143
2837
|
});
|
|
3144
2838
|
} else {
|