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