openxgen 1.0.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +2123 -1749
- package/dist/index.js.map +1 -1
- package/package.json +10 -2
package/dist/index.js
CHANGED
|
@@ -774,1888 +774,2225 @@ var init_provider = __esm({
|
|
|
774
774
|
}
|
|
775
775
|
});
|
|
776
776
|
|
|
777
|
-
// src/
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
const client2 = getClient();
|
|
788
|
-
const params = {};
|
|
789
|
-
if (collectionId) params.collection_id = collectionId;
|
|
790
|
-
const res = await client2.get("/api/documents/list", { params });
|
|
791
|
-
return res.data.documents ?? res.data ?? [];
|
|
792
|
-
}
|
|
793
|
-
async function uploadDocument(filePath, collectionId, name) {
|
|
794
|
-
const client2 = getClient();
|
|
795
|
-
const stat = statSync(filePath);
|
|
796
|
-
const fileName = name || basename(filePath);
|
|
797
|
-
const FormData = (await import("buffer")).Blob ? globalThis.FormData : null;
|
|
798
|
-
if (!FormData) throw new Error("FormData not available");
|
|
799
|
-
const form = new FormData();
|
|
800
|
-
const fileBlob = new Blob([createReadStream(filePath)]);
|
|
801
|
-
form.append("file", fileBlob, fileName);
|
|
802
|
-
if (collectionId) form.append("collection_id", collectionId);
|
|
803
|
-
const res = await client2.post("/api/documents/upload", form, {
|
|
804
|
-
headers: { "Content-Type": "multipart/form-data" },
|
|
805
|
-
maxBodyLength: stat.size + 1024 * 1024
|
|
806
|
-
});
|
|
807
|
-
return res.data;
|
|
777
|
+
// src/agent/llm.ts
|
|
778
|
+
import OpenAI2 from "openai";
|
|
779
|
+
function createLLMClient(provider) {
|
|
780
|
+
const opts = {
|
|
781
|
+
apiKey: provider.apiKey || "ollama"
|
|
782
|
+
};
|
|
783
|
+
if (provider.baseUrl) {
|
|
784
|
+
opts.baseURL = provider.baseUrl;
|
|
785
|
+
}
|
|
786
|
+
return new OpenAI2(opts);
|
|
808
787
|
}
|
|
809
|
-
async function
|
|
810
|
-
const
|
|
811
|
-
|
|
812
|
-
|
|
788
|
+
async function streamChat(client2, model, messages, tools2, onDelta) {
|
|
789
|
+
const params = {
|
|
790
|
+
model,
|
|
791
|
+
messages,
|
|
792
|
+
stream: true
|
|
793
|
+
};
|
|
794
|
+
if (tools2 && tools2.length > 0) {
|
|
795
|
+
params.tools = tools2;
|
|
796
|
+
}
|
|
797
|
+
const stream = await client2.chat.completions.create(params);
|
|
798
|
+
let content = "";
|
|
799
|
+
const toolCallMap = /* @__PURE__ */ new Map();
|
|
800
|
+
for await (const chunk of stream) {
|
|
801
|
+
const delta = chunk.choices[0]?.delta;
|
|
802
|
+
if (!delta) continue;
|
|
803
|
+
if (delta.content) {
|
|
804
|
+
content += delta.content;
|
|
805
|
+
onDelta?.(delta.content);
|
|
806
|
+
}
|
|
807
|
+
if (delta.tool_calls) {
|
|
808
|
+
for (const tc of delta.tool_calls) {
|
|
809
|
+
const idx = tc.index;
|
|
810
|
+
if (!toolCallMap.has(idx)) {
|
|
811
|
+
toolCallMap.set(idx, { id: tc.id ?? "", name: tc.function?.name ?? "", arguments: "" });
|
|
812
|
+
}
|
|
813
|
+
const entry = toolCallMap.get(idx);
|
|
814
|
+
if (tc.id) entry.id = tc.id;
|
|
815
|
+
if (tc.function?.name) entry.name = tc.function.name;
|
|
816
|
+
if (tc.function?.arguments) entry.arguments += tc.function.arguments;
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
return {
|
|
821
|
+
content,
|
|
822
|
+
toolCalls: [...toolCallMap.values()]
|
|
823
|
+
};
|
|
813
824
|
}
|
|
814
|
-
var
|
|
815
|
-
"src/
|
|
825
|
+
var init_llm = __esm({
|
|
826
|
+
"src/agent/llm.ts"() {
|
|
816
827
|
"use strict";
|
|
817
|
-
init_client();
|
|
818
828
|
}
|
|
819
829
|
});
|
|
820
830
|
|
|
821
|
-
// src/
|
|
822
|
-
var
|
|
823
|
-
__export(
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
queryGraphRAG: () => queryGraphRAG,
|
|
827
|
-
queryGraphRAGMultiTurn: () => queryGraphRAGMultiTurn
|
|
831
|
+
// src/agent/tools/file-read.ts
|
|
832
|
+
var file_read_exports = {};
|
|
833
|
+
__export(file_read_exports, {
|
|
834
|
+
definition: () => definition,
|
|
835
|
+
execute: () => execute
|
|
828
836
|
});
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
const
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
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 ?? [];
|
|
837
|
+
import { readFileSync as readFileSync2 } from "fs";
|
|
838
|
+
async function execute(args) {
|
|
839
|
+
const path = args.path;
|
|
840
|
+
const startLine = args.start_line || 1;
|
|
841
|
+
const endLine = args.end_line;
|
|
842
|
+
try {
|
|
843
|
+
const content = readFileSync2(path, "utf-8");
|
|
844
|
+
const lines = content.split("\n");
|
|
845
|
+
const sliced = lines.slice(startLine - 1, endLine ?? lines.length);
|
|
846
|
+
return sliced.map((line, i) => `${startLine + i} ${line}`).join("\n");
|
|
847
|
+
} catch (err) {
|
|
848
|
+
return `Error: ${err.message}`;
|
|
849
|
+
}
|
|
857
850
|
}
|
|
858
|
-
var
|
|
859
|
-
|
|
851
|
+
var definition;
|
|
852
|
+
var init_file_read = __esm({
|
|
853
|
+
"src/agent/tools/file-read.ts"() {
|
|
860
854
|
"use strict";
|
|
861
|
-
|
|
855
|
+
definition = {
|
|
856
|
+
type: "function",
|
|
857
|
+
function: {
|
|
858
|
+
name: "file_read",
|
|
859
|
+
description: "\uD30C\uC77C \uB0B4\uC6A9\uC744 \uC77D\uC2B5\uB2C8\uB2E4. \uC904 \uBC88\uD638\uAC00 \uD3EC\uD568\uB429\uB2C8\uB2E4.",
|
|
860
|
+
parameters: {
|
|
861
|
+
type: "object",
|
|
862
|
+
properties: {
|
|
863
|
+
path: { type: "string", description: "\uD30C\uC77C \uACBD\uB85C" },
|
|
864
|
+
start_line: { type: "number", description: "\uC2DC\uC791 \uC904 \uBC88\uD638 (\uC120\uD0DD)" },
|
|
865
|
+
end_line: { type: "number", description: "\uB05D \uC904 \uBC88\uD638 (\uC120\uD0DD)" }
|
|
866
|
+
},
|
|
867
|
+
required: ["path"]
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
};
|
|
862
871
|
}
|
|
863
872
|
});
|
|
864
873
|
|
|
865
|
-
// src/
|
|
866
|
-
|
|
867
|
-
|
|
874
|
+
// src/agent/tools/file-write.ts
|
|
875
|
+
var file_write_exports = {};
|
|
876
|
+
__export(file_write_exports, {
|
|
877
|
+
definition: () => definition2,
|
|
878
|
+
execute: () => execute2
|
|
879
|
+
});
|
|
880
|
+
import { writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "fs";
|
|
881
|
+
import { dirname } from "path";
|
|
882
|
+
async function execute2(args) {
|
|
883
|
+
const path = args.path;
|
|
884
|
+
const content = args.content;
|
|
885
|
+
try {
|
|
886
|
+
mkdirSync2(dirname(path), { recursive: true });
|
|
887
|
+
writeFileSync2(path, content, "utf-8");
|
|
888
|
+
return `\uD30C\uC77C \uC791\uC131 \uC644\uB8CC: ${path}`;
|
|
889
|
+
} catch (err) {
|
|
890
|
+
return `Error: ${err.message}`;
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
var definition2;
|
|
894
|
+
var init_file_write = __esm({
|
|
895
|
+
"src/agent/tools/file-write.ts"() {
|
|
896
|
+
"use strict";
|
|
897
|
+
definition2 = {
|
|
898
|
+
type: "function",
|
|
899
|
+
function: {
|
|
900
|
+
name: "file_write",
|
|
901
|
+
description: "\uD30C\uC77C\uC744 \uC0DD\uC131\uD558\uAC70\uB098 \uB36E\uC5B4\uC501\uB2C8\uB2E4.",
|
|
902
|
+
parameters: {
|
|
903
|
+
type: "object",
|
|
904
|
+
properties: {
|
|
905
|
+
path: { type: "string", description: "\uD30C\uC77C \uACBD\uB85C" },
|
|
906
|
+
content: { type: "string", description: "\uD30C\uC77C \uB0B4\uC6A9" }
|
|
907
|
+
},
|
|
908
|
+
required: ["path", "content"]
|
|
909
|
+
}
|
|
910
|
+
}
|
|
911
|
+
};
|
|
912
|
+
}
|
|
913
|
+
});
|
|
868
914
|
|
|
869
|
-
// src/
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
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);
|
|
915
|
+
// src/agent/tools/file-edit.ts
|
|
916
|
+
var file_edit_exports = {};
|
|
917
|
+
__export(file_edit_exports, {
|
|
918
|
+
definition: () => definition3,
|
|
919
|
+
execute: () => execute3
|
|
920
|
+
});
|
|
921
|
+
import { readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
|
|
922
|
+
async function execute3(args) {
|
|
923
|
+
const path = args.path;
|
|
924
|
+
const oldText = args.old_text;
|
|
925
|
+
const newText = args.new_text;
|
|
926
|
+
try {
|
|
927
|
+
const content = readFileSync3(path, "utf-8");
|
|
928
|
+
if (!content.includes(oldText)) {
|
|
929
|
+
return `Error: \uD14D\uC2A4\uD2B8\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4`;
|
|
910
930
|
}
|
|
911
|
-
const
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
})
|
|
931
|
+
const updated = content.replace(oldText, newText);
|
|
932
|
+
writeFileSync3(path, updated, "utf-8");
|
|
933
|
+
return `\uD30C\uC77C \uC218\uC815 \uC644\uB8CC: ${path}`;
|
|
934
|
+
} catch (err) {
|
|
935
|
+
return `Error: ${err.message}`;
|
|
936
|
+
}
|
|
915
937
|
}
|
|
938
|
+
var definition3;
|
|
939
|
+
var init_file_edit = __esm({
|
|
940
|
+
"src/agent/tools/file-edit.ts"() {
|
|
941
|
+
"use strict";
|
|
942
|
+
definition3 = {
|
|
943
|
+
type: "function",
|
|
944
|
+
function: {
|
|
945
|
+
name: "file_edit",
|
|
946
|
+
description: "\uD30C\uC77C\uC5D0\uC11C \uD2B9\uC815 \uD14D\uC2A4\uD2B8\uB97C \uCC3E\uC544 \uAD50\uCCB4\uD569\uB2C8\uB2E4.",
|
|
947
|
+
parameters: {
|
|
948
|
+
type: "object",
|
|
949
|
+
properties: {
|
|
950
|
+
path: { type: "string", description: "\uD30C\uC77C \uACBD\uB85C" },
|
|
951
|
+
old_text: { type: "string", description: "\uAD50\uCCB4\uD560 \uAE30\uC874 \uD14D\uC2A4\uD2B8" },
|
|
952
|
+
new_text: { type: "string", description: "\uC0C8 \uD14D\uC2A4\uD2B8" }
|
|
953
|
+
},
|
|
954
|
+
required: ["path", "old_text", "new_text"]
|
|
955
|
+
}
|
|
956
|
+
}
|
|
957
|
+
};
|
|
958
|
+
}
|
|
959
|
+
});
|
|
916
960
|
|
|
917
|
-
// src/
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
961
|
+
// src/agent/tools/bash.ts
|
|
962
|
+
var bash_exports = {};
|
|
963
|
+
__export(bash_exports, {
|
|
964
|
+
definition: () => definition4,
|
|
965
|
+
execute: () => execute4
|
|
966
|
+
});
|
|
967
|
+
import { execSync } from "child_process";
|
|
968
|
+
async function execute4(args) {
|
|
969
|
+
const command = args.command;
|
|
970
|
+
try {
|
|
971
|
+
const output = execSync(command, {
|
|
972
|
+
encoding: "utf-8",
|
|
973
|
+
timeout: 3e4,
|
|
974
|
+
maxBuffer: 1024 * 1024,
|
|
975
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
928
976
|
});
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
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
|
-
});
|
|
977
|
+
return output || "(no output)";
|
|
978
|
+
} catch (err) {
|
|
979
|
+
const e = err;
|
|
980
|
+
return (e.stdout || "") + (e.stderr || "") || `Error: ${e.message}`;
|
|
981
|
+
}
|
|
963
982
|
}
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
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")}`);
|
|
1029
|
-
}
|
|
1030
|
-
if (result.user_type) {
|
|
1031
|
-
console.log(` ${chalk3.gray("\uC720\uD615:")} ${result.user_type}`);
|
|
983
|
+
var definition4;
|
|
984
|
+
var init_bash = __esm({
|
|
985
|
+
"src/agent/tools/bash.ts"() {
|
|
986
|
+
"use strict";
|
|
987
|
+
definition4 = {
|
|
988
|
+
type: "function",
|
|
989
|
+
function: {
|
|
990
|
+
name: "bash",
|
|
991
|
+
description: "\uC178 \uBA85\uB839\uC5B4\uB97C \uC2E4\uD589\uD569\uB2C8\uB2E4. stdout + stderr\uB97C \uBC18\uD658\uD569\uB2C8\uB2E4.",
|
|
992
|
+
parameters: {
|
|
993
|
+
type: "object",
|
|
994
|
+
properties: {
|
|
995
|
+
command: { type: "string", description: "\uC2E4\uD589\uD560 \uBA85\uB839\uC5B4" }
|
|
996
|
+
},
|
|
997
|
+
required: ["command"]
|
|
1032
998
|
}
|
|
1033
|
-
} else {
|
|
1034
|
-
console.log(` ${chalk3.gray("\uC0C1\uD0DC:")} ${chalk3.red("\uD1A0\uD070 \uB9CC\uB8CC")}`);
|
|
1035
999
|
}
|
|
1036
|
-
}
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
console.log();
|
|
1040
|
-
});
|
|
1041
|
-
}
|
|
1000
|
+
};
|
|
1001
|
+
}
|
|
1002
|
+
});
|
|
1042
1003
|
|
|
1043
|
-
// src/
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1004
|
+
// src/agent/tools/grep.ts
|
|
1005
|
+
var grep_exports = {};
|
|
1006
|
+
__export(grep_exports, {
|
|
1007
|
+
definition: () => definition5,
|
|
1008
|
+
execute: () => execute5
|
|
1009
|
+
});
|
|
1010
|
+
import { execSync as execSync2 } from "child_process";
|
|
1011
|
+
async function execute5(args) {
|
|
1012
|
+
const pattern = args.pattern;
|
|
1013
|
+
const path = args.path || ".";
|
|
1014
|
+
const glob = args.glob;
|
|
1050
1015
|
try {
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
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
|
-
);
|
|
1069
|
-
} else {
|
|
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
|
-
);
|
|
1085
|
-
}
|
|
1086
|
-
console.log();
|
|
1087
|
-
} catch (err) {
|
|
1088
|
-
const msg = err.message;
|
|
1089
|
-
printError(`\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uBAA9\uB85D \uC870\uD68C \uC2E4\uD328: ${msg}`);
|
|
1090
|
-
process.exit(1);
|
|
1016
|
+
let cmd = `grep -rn --color=never "${pattern.replace(/"/g, '\\"')}" "${path}"`;
|
|
1017
|
+
if (glob) cmd += ` --include="${glob}"`;
|
|
1018
|
+
cmd += " | head -50";
|
|
1019
|
+
const output = execSync2(cmd, {
|
|
1020
|
+
encoding: "utf-8",
|
|
1021
|
+
timeout: 1e4,
|
|
1022
|
+
maxBuffer: 512 * 1024,
|
|
1023
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
1024
|
+
});
|
|
1025
|
+
return output || "\uC77C\uCE58\uD558\uB294 \uACB0\uACFC \uC5C6\uC74C";
|
|
1026
|
+
} catch {
|
|
1027
|
+
return "\uC77C\uCE58\uD558\uB294 \uACB0\uACFC \uC5C6\uC74C";
|
|
1091
1028
|
}
|
|
1092
1029
|
}
|
|
1030
|
+
var definition5;
|
|
1031
|
+
var init_grep = __esm({
|
|
1032
|
+
"src/agent/tools/grep.ts"() {
|
|
1033
|
+
"use strict";
|
|
1034
|
+
definition5 = {
|
|
1035
|
+
type: "function",
|
|
1036
|
+
function: {
|
|
1037
|
+
name: "grep",
|
|
1038
|
+
description: "\uD30C\uC77C\uC5D0\uC11C \uD328\uD134\uC744 \uAC80\uC0C9\uD569\uB2C8\uB2E4 (\uC7AC\uADC0, \uC904 \uBC88\uD638 \uD3EC\uD568).",
|
|
1039
|
+
parameters: {
|
|
1040
|
+
type: "object",
|
|
1041
|
+
properties: {
|
|
1042
|
+
pattern: { type: "string", description: "\uAC80\uC0C9 \uD328\uD134 (\uC815\uADDC\uC2DD)" },
|
|
1043
|
+
path: { type: "string", description: "\uAC80\uC0C9 \uB514\uB809\uD1A0\uB9AC \uB610\uB294 \uD30C\uC77C (\uAE30\uBCF8: .)" },
|
|
1044
|
+
glob: { type: "string", description: "\uD30C\uC77C \uD544\uD130 (\uC608: *.ts)" }
|
|
1045
|
+
},
|
|
1046
|
+
required: ["pattern"]
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
};
|
|
1050
|
+
}
|
|
1051
|
+
});
|
|
1093
1052
|
|
|
1094
|
-
// src/
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1053
|
+
// src/agent/tools/list-files.ts
|
|
1054
|
+
var list_files_exports = {};
|
|
1055
|
+
__export(list_files_exports, {
|
|
1056
|
+
definition: () => definition6,
|
|
1057
|
+
execute: () => execute6
|
|
1058
|
+
});
|
|
1059
|
+
import { execSync as execSync3 } from "child_process";
|
|
1060
|
+
async function execute6(args) {
|
|
1061
|
+
const path = args.path || ".";
|
|
1062
|
+
const pattern = args.pattern;
|
|
1101
1063
|
try {
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
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})`)}`);
|
|
1115
|
-
}
|
|
1116
|
-
}
|
|
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
|
-
}
|
|
1064
|
+
let cmd;
|
|
1065
|
+
if (pattern) {
|
|
1066
|
+
cmd = `find "${path}" -name "${pattern}" -type f | head -100`;
|
|
1067
|
+
} else {
|
|
1068
|
+
cmd = `ls -la "${path}"`;
|
|
1123
1069
|
}
|
|
1124
|
-
|
|
1070
|
+
const output = execSync3(cmd, {
|
|
1071
|
+
encoding: "utf-8",
|
|
1072
|
+
timeout: 1e4,
|
|
1073
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
1074
|
+
});
|
|
1075
|
+
return output || "(empty)";
|
|
1125
1076
|
} catch (err) {
|
|
1126
|
-
|
|
1127
|
-
printError(`\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uC870\uD68C \uC2E4\uD328: ${msg}`);
|
|
1128
|
-
process.exit(1);
|
|
1077
|
+
return `Error: ${err.message}`;
|
|
1129
1078
|
}
|
|
1130
1079
|
}
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
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);
|
|
1080
|
+
var definition6;
|
|
1081
|
+
var init_list_files = __esm({
|
|
1082
|
+
"src/agent/tools/list-files.ts"() {
|
|
1083
|
+
"use strict";
|
|
1084
|
+
definition6 = {
|
|
1085
|
+
type: "function",
|
|
1086
|
+
function: {
|
|
1087
|
+
name: "list_files",
|
|
1088
|
+
description: "\uB514\uB809\uD1A0\uB9AC\uC758 \uD30C\uC77C/\uD3F4\uB354 \uBAA9\uB85D\uC744 \uBC18\uD658\uD569\uB2C8\uB2E4. glob \uD328\uD134 \uC9C0\uC6D0.",
|
|
1089
|
+
parameters: {
|
|
1090
|
+
type: "object",
|
|
1091
|
+
properties: {
|
|
1092
|
+
path: { type: "string", description: "\uB514\uB809\uD1A0\uB9AC \uACBD\uB85C (\uAE30\uBCF8: .)" },
|
|
1093
|
+
pattern: { type: "string", description: "glob \uD328\uD134 (\uC608: **/*.ts)" }
|
|
1154
1094
|
}
|
|
1155
1095
|
}
|
|
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
1096
|
}
|
|
1097
|
+
};
|
|
1098
|
+
}
|
|
1099
|
+
});
|
|
1100
|
+
|
|
1101
|
+
// src/agent/tools/sandbox.ts
|
|
1102
|
+
var sandbox_exports = {};
|
|
1103
|
+
__export(sandbox_exports, {
|
|
1104
|
+
definition: () => definition7,
|
|
1105
|
+
execute: () => execute7
|
|
1106
|
+
});
|
|
1107
|
+
import { execSync as execSync4 } from "child_process";
|
|
1108
|
+
import { mkdirSync as mkdirSync3, writeFileSync as writeFileSync4, existsSync as existsSync2, rmSync } from "fs";
|
|
1109
|
+
import { join as join2 } from "path";
|
|
1110
|
+
import { tmpdir } from "os";
|
|
1111
|
+
function ensureSandbox() {
|
|
1112
|
+
if (!existsSync2(SANDBOX_DIR)) {
|
|
1113
|
+
mkdirSync3(SANDBOX_DIR, { recursive: true });
|
|
1114
|
+
}
|
|
1115
|
+
return SANDBOX_DIR;
|
|
1116
|
+
}
|
|
1117
|
+
async function execute7(args) {
|
|
1118
|
+
const language = args.language;
|
|
1119
|
+
const code = args.code;
|
|
1120
|
+
const packages = args.packages ?? [];
|
|
1121
|
+
const dir = ensureSandbox();
|
|
1122
|
+
const runId = `run_${Date.now()}`;
|
|
1123
|
+
const runDir = join2(dir, runId);
|
|
1124
|
+
mkdirSync3(runDir, { recursive: true });
|
|
1125
|
+
try {
|
|
1126
|
+
if (packages.length > 0) {
|
|
1127
|
+
if (language === "python") {
|
|
1128
|
+
const pkgList = packages.join(" ");
|
|
1129
|
+
execSync4(`pip install ${pkgList}`, {
|
|
1130
|
+
cwd: runDir,
|
|
1131
|
+
encoding: "utf-8",
|
|
1132
|
+
timeout: 6e4,
|
|
1133
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
1134
|
+
});
|
|
1135
|
+
} else {
|
|
1136
|
+
execSync4("npm init -y", { cwd: runDir, encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] });
|
|
1137
|
+
const pkgList = packages.join(" ");
|
|
1138
|
+
execSync4(`npm install ${pkgList}`, {
|
|
1139
|
+
cwd: runDir,
|
|
1140
|
+
encoding: "utf-8",
|
|
1141
|
+
timeout: 6e4,
|
|
1142
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
1143
|
+
});
|
|
1144
|
+
}
|
|
1145
|
+
}
|
|
1146
|
+
let cmd;
|
|
1147
|
+
let filename;
|
|
1148
|
+
if (language === "python") {
|
|
1149
|
+
filename = "script.py";
|
|
1150
|
+
writeFileSync4(join2(runDir, filename), code, "utf-8");
|
|
1151
|
+
cmd = `python3 ${filename}`;
|
|
1152
|
+
} else if (language === "typescript") {
|
|
1153
|
+
filename = "script.ts";
|
|
1154
|
+
writeFileSync4(join2(runDir, filename), code, "utf-8");
|
|
1155
|
+
cmd = `npx tsx ${filename}`;
|
|
1156
|
+
} else {
|
|
1157
|
+
filename = "script.mjs";
|
|
1158
|
+
writeFileSync4(join2(runDir, filename), code, "utf-8");
|
|
1159
|
+
cmd = `node ${filename}`;
|
|
1160
|
+
}
|
|
1161
|
+
const output = execSync4(cmd, {
|
|
1162
|
+
cwd: runDir,
|
|
1163
|
+
encoding: "utf-8",
|
|
1164
|
+
timeout: 3e4,
|
|
1165
|
+
maxBuffer: 1024 * 1024,
|
|
1166
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
1164
1167
|
});
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1168
|
+
return output || "(no output)";
|
|
1169
|
+
} catch (err) {
|
|
1170
|
+
const e = err;
|
|
1171
|
+
return (e.stdout || "") + (e.stderr || "") || `Error: ${e.message}`;
|
|
1172
|
+
} finally {
|
|
1173
|
+
try {
|
|
1174
|
+
rmSync(runDir, { recursive: true, force: true });
|
|
1175
|
+
} catch {
|
|
1176
|
+
}
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1179
|
+
var SANDBOX_DIR, definition7;
|
|
1180
|
+
var init_sandbox = __esm({
|
|
1181
|
+
"src/agent/tools/sandbox.ts"() {
|
|
1182
|
+
"use strict";
|
|
1183
|
+
SANDBOX_DIR = join2(tmpdir(), "xgen-sandbox");
|
|
1184
|
+
definition7 = {
|
|
1185
|
+
type: "function",
|
|
1186
|
+
function: {
|
|
1187
|
+
name: "sandbox_run",
|
|
1188
|
+
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.",
|
|
1189
|
+
parameters: {
|
|
1190
|
+
type: "object",
|
|
1191
|
+
properties: {
|
|
1192
|
+
language: {
|
|
1193
|
+
type: "string",
|
|
1194
|
+
enum: ["javascript", "typescript", "python"],
|
|
1195
|
+
description: "\uC2E4\uD589\uD560 \uC5B8\uC5B4"
|
|
1196
|
+
},
|
|
1197
|
+
code: { type: "string", description: "\uC2E4\uD589\uD560 \uCF54\uB4DC" },
|
|
1198
|
+
packages: {
|
|
1199
|
+
type: "array",
|
|
1200
|
+
items: { type: "string" },
|
|
1201
|
+
description: "\uC124\uCE58\uD560 \uD328\uD0A4\uC9C0 (npm \uB610\uB294 pip)"
|
|
1175
1202
|
}
|
|
1176
|
-
}
|
|
1203
|
+
},
|
|
1204
|
+
required: ["language", "code"]
|
|
1177
1205
|
}
|
|
1178
1206
|
}
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
stream.on("error", (err) => {
|
|
1183
|
-
onError?.(err);
|
|
1184
|
-
reject(err);
|
|
1185
|
-
});
|
|
1186
|
-
});
|
|
1187
|
-
}
|
|
1188
|
-
|
|
1189
|
-
// src/commands/workflow/run.ts
|
|
1190
|
-
init_format();
|
|
1207
|
+
};
|
|
1208
|
+
}
|
|
1209
|
+
});
|
|
1191
1210
|
|
|
1192
|
-
// src/
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
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;
|
|
1211
|
+
// src/agent/tools/index.ts
|
|
1212
|
+
function getAllToolDefs() {
|
|
1213
|
+
return tools.map((t) => t.definition);
|
|
1214
|
+
}
|
|
1215
|
+
async function executeTool(name, args) {
|
|
1216
|
+
const tool = toolMap.get(name);
|
|
1217
|
+
if (!tool) return `Unknown tool: ${name}`;
|
|
1218
|
+
return tool.execute(args);
|
|
1219
|
+
}
|
|
1220
|
+
function getToolNames() {
|
|
1221
|
+
return tools.map((t) => t.definition.function.name);
|
|
1222
1222
|
}
|
|
1223
|
+
var tools, toolMap;
|
|
1224
|
+
var init_tools = __esm({
|
|
1225
|
+
"src/agent/tools/index.ts"() {
|
|
1226
|
+
"use strict";
|
|
1227
|
+
init_file_read();
|
|
1228
|
+
init_file_write();
|
|
1229
|
+
init_file_edit();
|
|
1230
|
+
init_bash();
|
|
1231
|
+
init_grep();
|
|
1232
|
+
init_list_files();
|
|
1233
|
+
init_sandbox();
|
|
1234
|
+
tools = [file_read_exports, file_write_exports, file_edit_exports, bash_exports, grep_exports, list_files_exports, sandbox_exports];
|
|
1235
|
+
toolMap = /* @__PURE__ */ new Map();
|
|
1236
|
+
for (const t of tools) {
|
|
1237
|
+
toolMap.set(t.definition.function.name, t);
|
|
1238
|
+
}
|
|
1239
|
+
}
|
|
1240
|
+
});
|
|
1223
1241
|
|
|
1224
|
-
// src/
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1242
|
+
// src/api/document.ts
|
|
1243
|
+
var document_exports = {};
|
|
1244
|
+
__export(document_exports, {
|
|
1245
|
+
getDocumentInfo: () => getDocumentInfo,
|
|
1246
|
+
listCollections: () => listCollections,
|
|
1247
|
+
listDocuments: () => listDocuments,
|
|
1248
|
+
uploadDocument: () => uploadDocument
|
|
1249
|
+
});
|
|
1250
|
+
async function listCollections() {
|
|
1251
|
+
const client2 = getClient();
|
|
1252
|
+
const res = await client2.get("/api/retrieval/collections");
|
|
1253
|
+
return Array.isArray(res.data) ? res.data : res.data.collections ?? [];
|
|
1254
|
+
}
|
|
1255
|
+
async function listDocuments(collectionId) {
|
|
1256
|
+
const client2 = getClient();
|
|
1228
1257
|
try {
|
|
1229
|
-
const
|
|
1230
|
-
|
|
1258
|
+
const params = {};
|
|
1259
|
+
if (collectionId) params.collection_id = collectionId;
|
|
1260
|
+
const res = await client2.get("/api/retrieval/documents/list", { params });
|
|
1261
|
+
return res.data.documents ?? res.data ?? [];
|
|
1231
1262
|
} catch {
|
|
1263
|
+
return [];
|
|
1232
1264
|
}
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1265
|
+
}
|
|
1266
|
+
async function uploadDocument(filePath, collectionId, name) {
|
|
1267
|
+
const client2 = getClient();
|
|
1268
|
+
const { createReadStream, statSync } = await import("fs");
|
|
1269
|
+
const { basename } = await import("path");
|
|
1270
|
+
const stat = statSync(filePath);
|
|
1271
|
+
const fileName = name || basename(filePath);
|
|
1272
|
+
const form = new FormData();
|
|
1273
|
+
const fileBlob = new Blob([createReadStream(filePath)]);
|
|
1274
|
+
form.append("file", fileBlob, fileName);
|
|
1275
|
+
if (collectionId) form.append("collection_id", collectionId);
|
|
1276
|
+
const res = await client2.post("/api/retrieval/documents/upload", form, {
|
|
1277
|
+
headers: { "Content-Type": "multipart/form-data" },
|
|
1278
|
+
maxBodyLength: stat.size + 1024 * 1024
|
|
1279
|
+
});
|
|
1280
|
+
return res.data;
|
|
1281
|
+
}
|
|
1282
|
+
async function getDocumentInfo(docId) {
|
|
1283
|
+
const client2 = getClient();
|
|
1284
|
+
const res = await client2.get(`/api/retrieval/documents/${docId}`);
|
|
1285
|
+
return res.data;
|
|
1286
|
+
}
|
|
1287
|
+
var init_document = __esm({
|
|
1288
|
+
"src/api/document.ts"() {
|
|
1289
|
+
"use strict";
|
|
1290
|
+
init_client();
|
|
1249
1291
|
}
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1292
|
+
});
|
|
1293
|
+
|
|
1294
|
+
// src/agent/tools/xgen-api.ts
|
|
1295
|
+
async function execute8(name, args) {
|
|
1296
|
+
const server = getServer();
|
|
1297
|
+
const auth = getAuth();
|
|
1298
|
+
if (!server || !auth) {
|
|
1299
|
+
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.";
|
|
1253
1300
|
}
|
|
1254
|
-
const interactionId = `cli_${randomUUID().slice(0, 8)}`;
|
|
1255
|
-
printHeader(`\uC2E4\uD589: ${workflowName}`);
|
|
1256
|
-
printInfo(`\uC785\uB825: ${input}`);
|
|
1257
|
-
console.log();
|
|
1258
1301
|
try {
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1302
|
+
switch (name) {
|
|
1303
|
+
case "xgen_workflow_list":
|
|
1304
|
+
return await workflowList2();
|
|
1305
|
+
case "xgen_workflow_run":
|
|
1306
|
+
return await workflowRun2(args);
|
|
1307
|
+
case "xgen_workflow_info":
|
|
1308
|
+
return await workflowInfo2(args);
|
|
1309
|
+
case "xgen_collection_list":
|
|
1310
|
+
return await collectionList();
|
|
1311
|
+
case "xgen_server_status":
|
|
1312
|
+
return await serverStatus();
|
|
1313
|
+
case "xgen_execution_history":
|
|
1314
|
+
return await executionHistory(args);
|
|
1315
|
+
default:
|
|
1316
|
+
return `Unknown XGEN tool: ${name}`;
|
|
1317
|
+
}
|
|
1318
|
+
} catch (err) {
|
|
1319
|
+
return `XGEN API \uC624\uB958: ${err.message}`;
|
|
1320
|
+
}
|
|
1321
|
+
}
|
|
1322
|
+
function isXgenTool(name) {
|
|
1323
|
+
return name.startsWith("xgen_");
|
|
1324
|
+
}
|
|
1325
|
+
async function workflowList2() {
|
|
1326
|
+
const { getWorkflowListDetail: getWorkflowListDetail2 } = await Promise.resolve().then(() => (init_workflow(), workflow_exports));
|
|
1327
|
+
const wfs = await getWorkflowListDetail2();
|
|
1328
|
+
if (!wfs.length) return "\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uC5C6\uC74C.";
|
|
1329
|
+
return wfs.map((w, i) => {
|
|
1330
|
+
const deployed = w.is_deployed;
|
|
1331
|
+
const dk = w.deploy_key;
|
|
1332
|
+
const tag = deployed ? " [\uBC30\uD3EC\uB428]" : "";
|
|
1333
|
+
return `${i + 1}. ${w.workflow_name}${tag}
|
|
1334
|
+
ID: ${w.workflow_id ?? w.id}
|
|
1335
|
+
deploy_key: ${dk || "\uC5C6\uC74C"}`;
|
|
1336
|
+
}).join("\n");
|
|
1337
|
+
}
|
|
1338
|
+
async function workflowRun2(args) {
|
|
1339
|
+
const { executeWorkflow: executeWorkflow2 } = await Promise.resolve().then(() => (init_workflow(), workflow_exports));
|
|
1340
|
+
const { randomUUID: randomUUID4 } = await import("crypto");
|
|
1341
|
+
const result = await executeWorkflow2({
|
|
1342
|
+
workflow_id: args.workflow_id,
|
|
1343
|
+
workflow_name: args.workflow_name,
|
|
1344
|
+
input_data: args.input_data,
|
|
1345
|
+
interaction_id: `cli_${randomUUID4().slice(0, 8)}`,
|
|
1346
|
+
deploy_key: args.deploy_key
|
|
1347
|
+
});
|
|
1348
|
+
if (result.content) return String(result.content);
|
|
1349
|
+
if (result.success === false) return `\uC624\uB958: ${result.error ?? result.message}`;
|
|
1350
|
+
return JSON.stringify(result, null, 2).slice(0, 2e3);
|
|
1351
|
+
}
|
|
1352
|
+
async function workflowInfo2(args) {
|
|
1353
|
+
const { getWorkflowDetail: getWorkflowDetail2 } = await Promise.resolve().then(() => (init_workflow(), workflow_exports));
|
|
1354
|
+
const detail = await getWorkflowDetail2(args.workflow_id);
|
|
1355
|
+
const nodes = detail.nodes?.length ?? 0;
|
|
1356
|
+
const edges = detail.edges?.length ?? 0;
|
|
1357
|
+
return `\uC6CC\uD06C\uD50C\uB85C\uC6B0: ${detail.workflow_name}
|
|
1358
|
+
ID: ${detail.id}
|
|
1359
|
+
\uB178\uB4DC: ${nodes}\uAC1C
|
|
1360
|
+
\uC5E3\uC9C0: ${edges}\uAC1C`;
|
|
1361
|
+
}
|
|
1362
|
+
async function collectionList() {
|
|
1363
|
+
const { listCollections: listCollections2 } = await Promise.resolve().then(() => (init_document(), document_exports));
|
|
1364
|
+
const cols = await listCollections2();
|
|
1365
|
+
if (!cols.length) return "\uCEEC\uB809\uC158 \uC5C6\uC74C.";
|
|
1366
|
+
return cols.map((c, i) => {
|
|
1367
|
+
const shared = c.is_shared ? ` [\uACF5\uC720:${c.share_group}]` : "";
|
|
1368
|
+
return `${i + 1}. ${c.collection_make_name}${shared}
|
|
1369
|
+
\uBB38\uC11C: ${c.total_documents}\uAC1C \xB7 \uCCAD\uD06C: ${c.total_chunks}\uAC1C \xB7 \uBAA8\uB378: ${c.init_embedding_model ?? "-"}`;
|
|
1370
|
+
}).join("\n");
|
|
1371
|
+
}
|
|
1372
|
+
async function serverStatus() {
|
|
1373
|
+
const server = getServer();
|
|
1374
|
+
const auth = getAuth();
|
|
1375
|
+
return `\uC11C\uBC84: ${server}
|
|
1376
|
+
\uC0AC\uC6A9\uC790: ${auth?.username}
|
|
1377
|
+
User ID: ${auth?.userId}`;
|
|
1378
|
+
}
|
|
1379
|
+
async function executionHistory(args) {
|
|
1380
|
+
const { getIOLogs: getIOLogs2 } = await Promise.resolve().then(() => (init_workflow(), workflow_exports));
|
|
1381
|
+
const limit = args.limit || 10;
|
|
1382
|
+
const logs = await getIOLogs2(void 0, limit);
|
|
1383
|
+
if (!logs.length) return "\uC2E4\uD589 \uC774\uB825 \uC5C6\uC74C.";
|
|
1384
|
+
return logs.map(
|
|
1385
|
+
(l, i) => `${i + 1}. [${l.created_at ?? ""}]
|
|
1386
|
+
\uC785\uB825: ${(l.input_data ?? "").slice(0, 80)}
|
|
1387
|
+
\uCD9C\uB825: ${(l.output_data ?? "").slice(0, 80)}`
|
|
1388
|
+
).join("\n");
|
|
1389
|
+
}
|
|
1390
|
+
var definitions;
|
|
1391
|
+
var init_xgen_api = __esm({
|
|
1392
|
+
"src/agent/tools/xgen-api.ts"() {
|
|
1393
|
+
"use strict";
|
|
1394
|
+
init_store();
|
|
1395
|
+
definitions = [
|
|
1396
|
+
{
|
|
1397
|
+
type: "function",
|
|
1398
|
+
function: {
|
|
1399
|
+
name: "xgen_workflow_list",
|
|
1400
|
+
description: "XGEN \uC11C\uBC84\uC5D0\uC11C \uC6CC\uD06C\uD50C\uB85C\uC6B0 \uBAA9\uB85D\uC744 \uAC00\uC838\uC635\uB2C8\uB2E4.",
|
|
1401
|
+
parameters: { type: "object", properties: {} }
|
|
1317
1402
|
}
|
|
1318
1403
|
},
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1404
|
+
{
|
|
1405
|
+
type: "function",
|
|
1406
|
+
function: {
|
|
1407
|
+
name: "xgen_workflow_run",
|
|
1408
|
+
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.",
|
|
1409
|
+
parameters: {
|
|
1410
|
+
type: "object",
|
|
1411
|
+
properties: {
|
|
1412
|
+
workflow_id: { type: "string", description: "\uC6CC\uD06C\uD50C\uB85C\uC6B0 ID" },
|
|
1413
|
+
workflow_name: { type: "string", description: "\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uC774\uB984" },
|
|
1414
|
+
input_data: { type: "string", description: "\uC785\uB825 \uBA54\uC2DC\uC9C0" },
|
|
1415
|
+
deploy_key: { type: "string", description: "\uBC30\uD3EC \uD0A4 (\uBC30\uD3EC\uB41C \uC6CC\uD06C\uD50C\uB85C\uC6B0)" }
|
|
1416
|
+
},
|
|
1417
|
+
required: ["workflow_id", "workflow_name", "input_data"]
|
|
1325
1418
|
}
|
|
1326
1419
|
}
|
|
1327
|
-
console.log();
|
|
1328
|
-
console.log(chalk7.gray(`\uC138\uC158: ${interactionId}`));
|
|
1329
1420
|
},
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1421
|
+
{
|
|
1422
|
+
type: "function",
|
|
1423
|
+
function: {
|
|
1424
|
+
name: "xgen_workflow_info",
|
|
1425
|
+
description: "\uD2B9\uC815 \uC6CC\uD06C\uD50C\uB85C\uC6B0\uC758 \uC0C1\uC138 \uC815\uBCF4(\uB178\uB4DC, \uC5E3\uC9C0 \uB4F1)\uB97C \uAC00\uC838\uC635\uB2C8\uB2E4.",
|
|
1426
|
+
parameters: {
|
|
1427
|
+
type: "object",
|
|
1428
|
+
properties: {
|
|
1429
|
+
workflow_id: { type: "string", description: "\uC6CC\uD06C\uD50C\uB85C\uC6B0 ID" }
|
|
1430
|
+
},
|
|
1431
|
+
required: ["workflow_id"]
|
|
1432
|
+
}
|
|
1433
|
+
}
|
|
1434
|
+
},
|
|
1435
|
+
{
|
|
1436
|
+
type: "function",
|
|
1437
|
+
function: {
|
|
1438
|
+
name: "xgen_collection_list",
|
|
1439
|
+
description: "XGEN \uC11C\uBC84\uC758 \uBB38\uC11C \uCEEC\uB809\uC158(\uC9C0\uC2DD\uBCA0\uC774\uC2A4) \uBAA9\uB85D\uC744 \uAC00\uC838\uC635\uB2C8\uB2E4. \uBB38\uC11C \uC218, \uCCAD\uD06C \uC218, \uACF5\uC720 \uC0C1\uD0DC \uB4F1 \uD3EC\uD568.",
|
|
1440
|
+
parameters: { type: "object", properties: {} }
|
|
1441
|
+
}
|
|
1442
|
+
},
|
|
1443
|
+
{
|
|
1444
|
+
type: "function",
|
|
1445
|
+
function: {
|
|
1446
|
+
name: "xgen_server_status",
|
|
1447
|
+
description: "XGEN \uC11C\uBC84 \uC0C1\uD0DC\uB97C \uD655\uC778\uD569\uB2C8\uB2E4.",
|
|
1448
|
+
parameters: { type: "object", properties: {} }
|
|
1449
|
+
}
|
|
1450
|
+
},
|
|
1451
|
+
{
|
|
1452
|
+
type: "function",
|
|
1453
|
+
function: {
|
|
1454
|
+
name: "xgen_execution_history",
|
|
1455
|
+
description: "\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uC2E4\uD589 \uC774\uB825\uC744 \uAC00\uC838\uC635\uB2C8\uB2E4.",
|
|
1456
|
+
parameters: {
|
|
1457
|
+
type: "object",
|
|
1458
|
+
properties: {
|
|
1459
|
+
limit: { type: "number", description: "\uAC00\uC838\uC62C \uC774\uB825 \uC218 (\uAE30\uBCF8 10)" }
|
|
1460
|
+
}
|
|
1461
|
+
}
|
|
1462
|
+
}
|
|
1333
1463
|
}
|
|
1334
|
-
|
|
1335
|
-
} catch (err) {
|
|
1336
|
-
const msg = err?.response?.data?.detail ?? err.message;
|
|
1337
|
-
printError(`\uC2E4\uD589 \uC2E4\uD328: ${msg}`);
|
|
1338
|
-
process.exit(1);
|
|
1464
|
+
];
|
|
1339
1465
|
}
|
|
1340
|
-
}
|
|
1466
|
+
});
|
|
1341
1467
|
|
|
1342
|
-
// src/
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
import
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
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
|
-
);
|
|
1468
|
+
// src/mcp/client.ts
|
|
1469
|
+
import { spawn } from "child_process";
|
|
1470
|
+
import { existsSync as existsSync3, readFileSync as readFileSync4 } from "fs";
|
|
1471
|
+
import { join as join3 } from "path";
|
|
1472
|
+
import { createInterface as createInterface4 } from "readline";
|
|
1473
|
+
function loadMcpConfig(dir) {
|
|
1474
|
+
const searchPaths = [
|
|
1475
|
+
dir ? join3(dir, ".mcp.json") : null,
|
|
1476
|
+
join3(process.cwd(), ".mcp.json"),
|
|
1477
|
+
join3(process.env.HOME ?? "", ".mcp.json")
|
|
1478
|
+
].filter(Boolean);
|
|
1479
|
+
for (const p of searchPaths) {
|
|
1480
|
+
if (existsSync3(p)) {
|
|
1481
|
+
try {
|
|
1482
|
+
return JSON.parse(readFileSync4(p, "utf-8"));
|
|
1483
|
+
} catch {
|
|
1484
|
+
continue;
|
|
1370
1485
|
}
|
|
1371
|
-
console.log();
|
|
1372
1486
|
}
|
|
1373
|
-
} catch (err) {
|
|
1374
|
-
const msg = err.message;
|
|
1375
|
-
printError(`\uC774\uB825 \uC870\uD68C \uC2E4\uD328: ${msg}`);
|
|
1376
|
-
process.exit(1);
|
|
1377
1487
|
}
|
|
1488
|
+
return null;
|
|
1378
1489
|
}
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
`);
|
|
1412
|
-
}
|
|
1413
|
-
async function promptLine(rl, promptStr) {
|
|
1414
|
-
return new Promise((resolve) => {
|
|
1415
|
-
rl.question(promptStr, (answer) => resolve(answer));
|
|
1416
|
-
});
|
|
1417
|
-
}
|
|
1418
|
-
async function chat(workflowId) {
|
|
1419
|
-
const auth = requireAuth();
|
|
1420
|
-
const server = getServer();
|
|
1421
|
-
let workflows = [];
|
|
1422
|
-
try {
|
|
1423
|
-
workflows = await listWorkflows();
|
|
1424
|
-
} catch {
|
|
1425
|
-
printError("\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uBAA9\uB85D\uC744 \uBD88\uB7EC\uC62C \uC218 \uC5C6\uC2B5\uB2C8\uB2E4");
|
|
1426
|
-
process.exit(1);
|
|
1427
|
-
}
|
|
1428
|
-
if (workflows.length === 0) {
|
|
1429
|
-
printError("\uC0AC\uC6A9 \uAC00\uB2A5\uD55C \uC6CC\uD06C\uD50C\uB85C\uC6B0\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4");
|
|
1430
|
-
process.exit(1);
|
|
1431
|
-
}
|
|
1432
|
-
let current;
|
|
1433
|
-
if (workflowId) {
|
|
1434
|
-
const found = workflows.find((w) => w.id === workflowId || w.workflow_name === workflowId);
|
|
1435
|
-
current = found ?? { id: workflowId, workflow_name: workflowId };
|
|
1436
|
-
} else {
|
|
1437
|
-
console.log(CHAT_BANNER);
|
|
1438
|
-
console.log(chalk9.gray(` \uC11C\uBC84: ${server} | \uC0AC\uC6A9\uC790: ${auth.username}
|
|
1439
|
-
`));
|
|
1440
|
-
console.log(chalk9.bold(" \uC6CC\uD06C\uD50C\uB85C\uC6B0 \uC120\uD0DD:\n"));
|
|
1441
|
-
workflows.forEach((w, i) => {
|
|
1442
|
-
console.log(` ${chalk9.cyan(String(i + 1).padStart(3))} ${w.workflow_name}`);
|
|
1443
|
-
});
|
|
1444
|
-
console.log();
|
|
1445
|
-
const rl2 = createInterface2({ input: process.stdin, output: process.stdout });
|
|
1446
|
-
const answer = await promptLine(rl2, chalk9.cyan(" \uBC88\uD638> "));
|
|
1447
|
-
rl2.close();
|
|
1448
|
-
const idx = parseInt(answer.trim()) - 1;
|
|
1449
|
-
if (isNaN(idx) || idx < 0 || idx >= workflows.length) {
|
|
1450
|
-
current = workflows[0];
|
|
1451
|
-
} else {
|
|
1452
|
-
current = workflows[idx];
|
|
1453
|
-
}
|
|
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":
|
|
1493
|
-
console.log();
|
|
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}`);
|
|
1497
|
-
});
|
|
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}
|
|
1511
|
-
`));
|
|
1512
|
-
}
|
|
1513
|
-
break;
|
|
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}`);
|
|
1490
|
+
var McpClient, McpManager;
|
|
1491
|
+
var init_client2 = __esm({
|
|
1492
|
+
"src/mcp/client.ts"() {
|
|
1493
|
+
"use strict";
|
|
1494
|
+
McpClient = class {
|
|
1495
|
+
process = null;
|
|
1496
|
+
requestId = 0;
|
|
1497
|
+
pending = /* @__PURE__ */ new Map();
|
|
1498
|
+
serverName;
|
|
1499
|
+
config;
|
|
1500
|
+
tools = [];
|
|
1501
|
+
constructor(serverName, config) {
|
|
1502
|
+
this.serverName = serverName;
|
|
1503
|
+
this.config = config;
|
|
1504
|
+
}
|
|
1505
|
+
async start() {
|
|
1506
|
+
this.process = spawn(this.config.command, this.config.args ?? [], {
|
|
1507
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
1508
|
+
env: { ...process.env, ...this.config.env }
|
|
1509
|
+
});
|
|
1510
|
+
const rl = createInterface4({ input: this.process.stdout });
|
|
1511
|
+
rl.on("line", (line) => {
|
|
1512
|
+
try {
|
|
1513
|
+
const msg = JSON.parse(line);
|
|
1514
|
+
if (msg.id !== void 0 && this.pending.has(msg.id)) {
|
|
1515
|
+
const p = this.pending.get(msg.id);
|
|
1516
|
+
this.pending.delete(msg.id);
|
|
1517
|
+
if (msg.error) {
|
|
1518
|
+
p.reject(new Error(msg.error.message));
|
|
1519
|
+
} else {
|
|
1520
|
+
p.resolve(msg.result);
|
|
1521
|
+
}
|
|
1525
1522
|
}
|
|
1526
|
-
|
|
1523
|
+
} catch {
|
|
1527
1524
|
}
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
console.
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
default:
|
|
1539
|
-
console.log(chalk9.yellow(` \uC54C \uC218 \uC5C6\uB294 \uCEE4\uB9E8\uB4DC: /${cmd}. /help \uCC38\uACE0`));
|
|
1525
|
+
});
|
|
1526
|
+
this.process.on("error", (err) => {
|
|
1527
|
+
console.error(`MCP [${this.serverName}] \uD504\uB85C\uC138\uC2A4 \uC624\uB958:`, err.message);
|
|
1528
|
+
});
|
|
1529
|
+
await this.send("initialize", {
|
|
1530
|
+
protocolVersion: "2024-11-05",
|
|
1531
|
+
capabilities: {},
|
|
1532
|
+
clientInfo: { name: "open-xgen", version: "0.3.0" }
|
|
1533
|
+
});
|
|
1534
|
+
await this.send("notifications/initialized", {});
|
|
1540
1535
|
}
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
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();
|
|
1536
|
+
send(method, params) {
|
|
1537
|
+
return new Promise((resolve, reject) => {
|
|
1538
|
+
const id = ++this.requestId;
|
|
1539
|
+
const request = { jsonrpc: "2.0", id, method, params };
|
|
1540
|
+
this.pending.set(id, { resolve, reject });
|
|
1541
|
+
const timeout = setTimeout(() => {
|
|
1542
|
+
this.pending.delete(id);
|
|
1543
|
+
reject(new Error(`MCP \uC694\uCCAD \uD0C0\uC784\uC544\uC6C3: ${method}`));
|
|
1544
|
+
}, 15e3);
|
|
1545
|
+
this.pending.set(id, {
|
|
1546
|
+
resolve: (v) => {
|
|
1547
|
+
clearTimeout(timeout);
|
|
1548
|
+
resolve(v);
|
|
1549
|
+
},
|
|
1550
|
+
reject: (e) => {
|
|
1551
|
+
clearTimeout(timeout);
|
|
1552
|
+
reject(e);
|
|
1565
1553
|
}
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1554
|
+
});
|
|
1555
|
+
this.process?.stdin?.write(JSON.stringify(request) + "\n");
|
|
1556
|
+
});
|
|
1557
|
+
}
|
|
1558
|
+
async listTools() {
|
|
1559
|
+
const result = await this.send("tools/list", {});
|
|
1560
|
+
this.tools = result.tools ?? [];
|
|
1561
|
+
return this.tools;
|
|
1562
|
+
}
|
|
1563
|
+
async callTool(name, args) {
|
|
1564
|
+
const result = await this.send("tools/call", { name, arguments: args });
|
|
1565
|
+
return result.content?.map((c) => c.text ?? "").join("\n") ?? "";
|
|
1566
|
+
}
|
|
1567
|
+
getOpenAITools() {
|
|
1568
|
+
return this.tools.map((t) => ({
|
|
1569
|
+
type: "function",
|
|
1570
|
+
function: {
|
|
1571
|
+
name: `mcp_${this.serverName}_${t.name}`,
|
|
1572
|
+
description: `[MCP:${this.serverName}] ${t.description ?? t.name}`,
|
|
1573
|
+
parameters: t.inputSchema ?? { type: "object", properties: {} }
|
|
1577
1574
|
}
|
|
1578
|
-
|
|
1579
|
-
|
|
1575
|
+
}));
|
|
1576
|
+
}
|
|
1577
|
+
stop() {
|
|
1578
|
+
this.process?.kill();
|
|
1579
|
+
this.process = null;
|
|
1580
|
+
}
|
|
1581
|
+
};
|
|
1582
|
+
McpManager = class {
|
|
1583
|
+
clients = /* @__PURE__ */ new Map();
|
|
1584
|
+
async startAll(config) {
|
|
1585
|
+
for (const [name, serverConfig] of Object.entries(config.mcpServers)) {
|
|
1586
|
+
if (serverConfig.type !== "stdio") continue;
|
|
1587
|
+
try {
|
|
1588
|
+
const client2 = new McpClient(name, serverConfig);
|
|
1589
|
+
await client2.start();
|
|
1590
|
+
await client2.listTools();
|
|
1591
|
+
this.clients.set(name, client2);
|
|
1592
|
+
} catch (err) {
|
|
1593
|
+
console.error(`MCP [${name}] \uC2DC\uC791 \uC2E4\uD328:`, err.message);
|
|
1580
1594
|
}
|
|
1581
|
-
},
|
|
1582
|
-
(err) => {
|
|
1583
|
-
process.stdout.write("\r" + " ".repeat(20) + "\r");
|
|
1584
|
-
printError(`\uC2A4\uD2B8\uB9AC\uBC0D \uC624\uB958: ${err.message}`);
|
|
1585
1595
|
}
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
}
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1596
|
+
}
|
|
1597
|
+
getAllTools() {
|
|
1598
|
+
const tools2 = [];
|
|
1599
|
+
for (const client2 of this.clients.values()) {
|
|
1600
|
+
tools2.push(...client2.getOpenAITools());
|
|
1601
|
+
}
|
|
1602
|
+
return tools2;
|
|
1603
|
+
}
|
|
1604
|
+
async callTool(fullName, args) {
|
|
1605
|
+
const parts = fullName.split("_");
|
|
1606
|
+
if (parts.length < 3 || parts[0] !== "mcp") return `Unknown MCP tool: ${fullName}`;
|
|
1607
|
+
const serverName = parts[1];
|
|
1608
|
+
const toolName = parts.slice(2).join("_");
|
|
1609
|
+
const client2 = this.clients.get(serverName);
|
|
1610
|
+
if (!client2) return `MCP \uC11C\uBC84\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${serverName}`;
|
|
1611
|
+
return client2.callTool(toolName, args);
|
|
1612
|
+
}
|
|
1613
|
+
isMcpTool(name) {
|
|
1614
|
+
return name.startsWith("mcp_");
|
|
1615
|
+
}
|
|
1616
|
+
stopAll() {
|
|
1617
|
+
for (const client2 of this.clients.values()) {
|
|
1618
|
+
client2.stop();
|
|
1619
|
+
}
|
|
1620
|
+
this.clients.clear();
|
|
1621
|
+
}
|
|
1622
|
+
get serverCount() {
|
|
1623
|
+
return this.clients.size;
|
|
1624
|
+
}
|
|
1625
|
+
getServerNames() {
|
|
1626
|
+
return [...this.clients.keys()];
|
|
1627
|
+
}
|
|
1628
|
+
};
|
|
1629
|
+
}
|
|
1630
|
+
});
|
|
1615
1631
|
|
|
1616
1632
|
// src/commands/agent.ts
|
|
1617
|
-
init_store();
|
|
1618
1633
|
import chalk12 from "chalk";
|
|
1619
1634
|
import { createInterface as createInterface5 } from "readline";
|
|
1635
|
+
function buildSystemPrompt() {
|
|
1636
|
+
const server = getServer();
|
|
1637
|
+
const auth = getAuth();
|
|
1638
|
+
const env = getActiveEnvironment();
|
|
1639
|
+
let prompt2 = `You are OPEN XGEN. Terminal AI agent.
|
|
1620
1640
|
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1641
|
+
CRITICAL RULES:
|
|
1642
|
+
- Be extremely concise. No menus, no numbered lists of options, no "what would you like to do" questions.
|
|
1643
|
+
- Just DO things. If the user says "\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uBAA9\uB85D" \u2192 call xgen_workflow_list immediately, show results.
|
|
1644
|
+
- If the user says a number after seeing a list, treat it as selection and act on it.
|
|
1645
|
+
- If the user says "\uC2E4\uD589" or "run" \u2192 call the tool immediately with the context you have.
|
|
1646
|
+
- Never ask "which option do you prefer" or show menus. Infer intent and act.
|
|
1647
|
+
- Respond in the user's language. Korean if they speak Korean.
|
|
1648
|
+
- Max 2-3 sentences per response unless showing data.
|
|
1649
|
+
|
|
1650
|
+
TOOLS:
|
|
1651
|
+
- Coding: file_read, file_write, file_edit, bash, grep, list_files, sandbox_run
|
|
1652
|
+
- XGEN: xgen_workflow_list, xgen_workflow_run, xgen_workflow_info, xgen_doc_list, xgen_ontology_query, xgen_server_status, xgen_execution_history`;
|
|
1653
|
+
if (server && auth) {
|
|
1654
|
+
prompt2 += `
|
|
1655
|
+
|
|
1656
|
+
XGEN CONNECTED: ${server} as ${auth.username} (${env?.name ?? "default"})
|
|
1657
|
+
- Workflow execute uses deploy_key for deployed workflows.
|
|
1658
|
+
- If workflow execution returns 404, it means the Istio routing blocks direct stream access. Use deploy endpoint.`;
|
|
1659
|
+
} else {
|
|
1660
|
+
prompt2 += `
|
|
1661
|
+
XGEN: Not connected. Tell user to run /connect.`;
|
|
1629
1662
|
}
|
|
1630
|
-
return
|
|
1663
|
+
return prompt2;
|
|
1631
1664
|
}
|
|
1632
|
-
async function
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
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);
|
|
1650
|
-
}
|
|
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;
|
|
1661
|
-
}
|
|
1662
|
-
}
|
|
1665
|
+
async function agentRepl() {
|
|
1666
|
+
let provider = getDefaultProvider();
|
|
1667
|
+
if (!provider) {
|
|
1668
|
+
provider = await guidedProviderSetup();
|
|
1669
|
+
if (!provider) process.exit(1);
|
|
1663
1670
|
}
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
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"]
|
|
1671
|
+
const client2 = createLLMClient(provider);
|
|
1672
|
+
const allTools = [...getAllToolDefs(), ...definitions];
|
|
1673
|
+
const builtinNames = getToolNames();
|
|
1674
|
+
const mcpConfig = loadMcpConfig();
|
|
1675
|
+
if (mcpConfig && Object.keys(mcpConfig.mcpServers).length > 0) {
|
|
1676
|
+
mcpManager = new McpManager();
|
|
1677
|
+
try {
|
|
1678
|
+
await mcpManager.startAll(mcpConfig);
|
|
1679
|
+
if (mcpManager.serverCount > 0) allTools.push(...mcpManager.getAllTools());
|
|
1680
|
+
} catch {
|
|
1690
1681
|
}
|
|
1691
1682
|
}
|
|
1692
|
-
};
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
const
|
|
1696
|
-
const
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
return sliced.map((line, i) => `${startLine + i} ${line}`).join("\n");
|
|
1702
|
-
} catch (err) {
|
|
1703
|
-
return `Error: ${err.message}`;
|
|
1683
|
+
const messages = [{ role: "system", content: buildSystemPrompt() }];
|
|
1684
|
+
console.log(welcome());
|
|
1685
|
+
console.log();
|
|
1686
|
+
const server = getServer();
|
|
1687
|
+
const auth = getAuth();
|
|
1688
|
+
const env = getActiveEnvironment();
|
|
1689
|
+
console.log(chalk12.gray(` ${provider.name} \xB7 ${provider.model}`));
|
|
1690
|
+
if (server && auth) {
|
|
1691
|
+
console.log(chalk12.gray(` ${env?.name ?? "XGEN"} \xB7 ${auth.username}@${server.replace("https://", "")}`));
|
|
1704
1692
|
}
|
|
1705
|
-
}
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
content: { type: "string", description: "\uD30C\uC77C \uB0B4\uC6A9" }
|
|
1725
|
-
},
|
|
1726
|
-
required: ["path", "content"]
|
|
1693
|
+
console.log(chalk12.gray(` ${builtinNames.length} \uB3C4\uAD6C + ${definitions.length} XGEN${mcpManager?.serverCount ? ` + ${mcpManager.getAllTools().length} MCP` : ""}`));
|
|
1694
|
+
console.log(chalk12.gray(` /help \xB7 /connect \xB7 /env \xB7 /provider \xB7 /exit
|
|
1695
|
+
`));
|
|
1696
|
+
const rl = createInterface5({ input: process.stdin, output: process.stdout });
|
|
1697
|
+
const askUser = () => new Promise((resolve) => rl.question(chalk12.cyan(" \u276F "), (a) => resolve(a.trim())));
|
|
1698
|
+
process.on("SIGINT", () => {
|
|
1699
|
+
console.log(chalk12.gray("\n \u{1F44B}\n"));
|
|
1700
|
+
mcpManager?.stopAll();
|
|
1701
|
+
rl.close();
|
|
1702
|
+
process.exit(0);
|
|
1703
|
+
});
|
|
1704
|
+
while (true) {
|
|
1705
|
+
const input = await askUser();
|
|
1706
|
+
if (!input) continue;
|
|
1707
|
+
if (input === "/exit" || input === "exit") {
|
|
1708
|
+
console.log(chalk12.gray("\n \u{1F44B}\n"));
|
|
1709
|
+
mcpManager?.stopAll();
|
|
1710
|
+
rl.close();
|
|
1711
|
+
break;
|
|
1727
1712
|
}
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
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"]
|
|
1713
|
+
if (input === "/help") {
|
|
1714
|
+
console.log(`
|
|
1715
|
+
${chalk12.bold("\uC2AC\uB798\uC2DC \uCEE4\uB9E8\uB4DC")}
|
|
1716
|
+
${chalk12.cyan("/connect")} XGEN \uC11C\uBC84 \uC5F0\uACB0 + \uB85C\uADF8\uC778
|
|
1717
|
+
${chalk12.cyan("/env")} \uD658\uACBD \uC804\uD658 (\uBCF8\uC0AC/\uC81C\uC8FC/\uB86F\uB370\uBAB0)
|
|
1718
|
+
${chalk12.cyan("/provider")} \uD504\uB85C\uBC14\uC774\uB354 \uBCC0\uACBD
|
|
1719
|
+
${chalk12.cyan("/tools")} \uC0AC\uC6A9 \uAC00\uB2A5\uD55C \uB3C4\uAD6C \uBAA9\uB85D
|
|
1720
|
+
${chalk12.cyan("/status")} \uD604\uC7AC \uC5F0\uACB0 \uC0C1\uD0DC
|
|
1721
|
+
${chalk12.cyan("/clear")} \uB300\uD654 \uCD08\uAE30\uD654
|
|
1722
|
+
${chalk12.cyan("/exit")} \uC885\uB8CC
|
|
1723
|
+
`);
|
|
1724
|
+
continue;
|
|
1762
1725
|
}
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
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`;
|
|
1726
|
+
if (input === "/clear") {
|
|
1727
|
+
messages.length = 0;
|
|
1728
|
+
messages.push({ role: "system", content: buildSystemPrompt() });
|
|
1729
|
+
console.log(chalk12.gray(" \uB300\uD654 \uCD08\uAE30\uD654\uB428.\n"));
|
|
1730
|
+
continue;
|
|
1773
1731
|
}
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
}
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1732
|
+
if (input === "/status") {
|
|
1733
|
+
const p = getDefaultProvider();
|
|
1734
|
+
const s = getServer();
|
|
1735
|
+
const a = getAuth();
|
|
1736
|
+
const e = getActiveEnvironment();
|
|
1737
|
+
console.log();
|
|
1738
|
+
console.log(` ${chalk12.bold("\uD504\uB85C\uBC14\uC774\uB354")} ${p ? `${p.name} \xB7 ${p.model}` : chalk12.red("\uBBF8\uC124\uC815")}`);
|
|
1739
|
+
console.log(` ${chalk12.bold("\uC11C\uBC84")} ${s && a ? `${a.username}@${s.replace("https://", "")}` : chalk12.red("\uBBF8\uC5F0\uACB0")}`);
|
|
1740
|
+
console.log(` ${chalk12.bold("\uD658\uACBD")} ${e?.name ?? "\uC5C6\uC74C"} (${getEnvironments().length}\uAC1C \uB4F1\uB85D)`);
|
|
1741
|
+
if (mcpManager?.serverCount) {
|
|
1742
|
+
console.log(` ${chalk12.bold("MCP")} ${mcpManager.getServerNames().join(", ")}`);
|
|
1743
|
+
}
|
|
1744
|
+
console.log();
|
|
1745
|
+
continue;
|
|
1746
|
+
}
|
|
1747
|
+
if (input === "/tools") {
|
|
1748
|
+
console.log(`
|
|
1749
|
+
${chalk12.bold("\uCF54\uB529")} ${builtinNames.join(", ")}`);
|
|
1750
|
+
console.log(` ${chalk12.bold("XGEN")} ${definitions.map((t) => t.function.name).join(", ")}`);
|
|
1751
|
+
if (mcpManager?.serverCount) {
|
|
1752
|
+
console.log(` ${chalk12.bold("MCP")} ${mcpManager.getAllTools().map((t) => t.function.name).join(", ")}`);
|
|
1753
|
+
}
|
|
1754
|
+
console.log();
|
|
1755
|
+
continue;
|
|
1756
|
+
}
|
|
1757
|
+
if (input === "/connect") {
|
|
1758
|
+
await connectServer();
|
|
1759
|
+
messages[0] = { role: "system", content: buildSystemPrompt() };
|
|
1760
|
+
continue;
|
|
1761
|
+
}
|
|
1762
|
+
if (input === "/env") {
|
|
1763
|
+
await switchEnv();
|
|
1764
|
+
messages[0] = { role: "system", content: buildSystemPrompt() };
|
|
1765
|
+
continue;
|
|
1766
|
+
}
|
|
1767
|
+
if (input === "/provider") {
|
|
1768
|
+
const { guidedProviderSetup: setup } = await Promise.resolve().then(() => (init_provider(), provider_exports));
|
|
1769
|
+
await setup();
|
|
1770
|
+
console.log(chalk12.gray(" \uD504\uB85C\uBC14\uC774\uB354 \uBCC0\uACBD\uB428. /exit \uD6C4 \uC7AC\uC2DC\uC791\uD558\uC138\uC694.\n"));
|
|
1771
|
+
continue;
|
|
1772
|
+
}
|
|
1773
|
+
messages.push({ role: "user", content: input });
|
|
1774
|
+
try {
|
|
1775
|
+
await runLoop(client2, provider.model, messages, allTools);
|
|
1776
|
+
} catch (err) {
|
|
1777
|
+
console.log(chalk12.red(`
|
|
1778
|
+
\uC624\uB958: ${err.message}
|
|
1779
|
+
`));
|
|
1800
1780
|
}
|
|
1801
|
-
}
|
|
1802
|
-
};
|
|
1803
|
-
async function execute4(args) {
|
|
1804
|
-
const command = args.command;
|
|
1805
|
-
try {
|
|
1806
|
-
const output = execSync(command, {
|
|
1807
|
-
encoding: "utf-8",
|
|
1808
|
-
timeout: 3e4,
|
|
1809
|
-
maxBuffer: 1024 * 1024,
|
|
1810
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
1811
|
-
});
|
|
1812
|
-
return output || "(no output)";
|
|
1813
|
-
} catch (err) {
|
|
1814
|
-
const e = err;
|
|
1815
|
-
return (e.stdout || "") + (e.stderr || "") || `Error: ${e.message}`;
|
|
1816
1781
|
}
|
|
1817
1782
|
}
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
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"]
|
|
1783
|
+
async function runLoop(client2, model, messages, tools2) {
|
|
1784
|
+
for (let i = 0; i < 20; i++) {
|
|
1785
|
+
let first = true;
|
|
1786
|
+
const result = await streamChat(client2, model, messages, tools2, (delta) => {
|
|
1787
|
+
if (first) {
|
|
1788
|
+
process.stdout.write(chalk12.green("\n ") + "");
|
|
1789
|
+
first = false;
|
|
1790
|
+
}
|
|
1791
|
+
process.stdout.write(delta);
|
|
1792
|
+
});
|
|
1793
|
+
if (result.content) process.stdout.write("\n\n");
|
|
1794
|
+
if (result.toolCalls.length === 0) {
|
|
1795
|
+
if (result.content) messages.push({ role: "assistant", content: result.content });
|
|
1796
|
+
return;
|
|
1839
1797
|
}
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
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"]
|
|
1798
|
+
messages.push({
|
|
1799
|
+
role: "assistant",
|
|
1800
|
+
content: result.content || null,
|
|
1801
|
+
tool_calls: result.toolCalls.map((tc) => ({
|
|
1802
|
+
id: tc.id,
|
|
1803
|
+
type: "function",
|
|
1804
|
+
function: { name: tc.name, arguments: tc.arguments }
|
|
1805
|
+
}))
|
|
1855
1806
|
});
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
}
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
});
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
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)" }
|
|
1807
|
+
for (const tc of result.toolCalls) {
|
|
1808
|
+
let args;
|
|
1809
|
+
try {
|
|
1810
|
+
args = JSON.parse(tc.arguments);
|
|
1811
|
+
} catch {
|
|
1812
|
+
args = {};
|
|
1813
|
+
}
|
|
1814
|
+
const shortArgs = Object.entries(args).map(([k, v]) => {
|
|
1815
|
+
const s = String(v);
|
|
1816
|
+
return `${k}=${s.length > 30 ? s.slice(0, 30) + "\u2026" : s}`;
|
|
1817
|
+
}).join(" ");
|
|
1818
|
+
console.log(chalk12.gray(` \u2699 ${chalk12.white(tc.name)} ${shortArgs}`));
|
|
1819
|
+
let toolResult;
|
|
1820
|
+
if (isXgenTool(tc.name)) {
|
|
1821
|
+
toolResult = await execute8(tc.name, args);
|
|
1822
|
+
} else if (mcpManager?.isMcpTool(tc.name)) {
|
|
1823
|
+
toolResult = await mcpManager.callTool(tc.name, args);
|
|
1824
|
+
} else {
|
|
1825
|
+
toolResult = await executeTool(tc.name, args);
|
|
1879
1826
|
}
|
|
1827
|
+
const truncated = toolResult.length > 4e3 ? toolResult.slice(0, 4e3) + "\n\u2026(truncated)" : toolResult;
|
|
1828
|
+
messages.push({ role: "tool", tool_call_id: tc.id, content: truncated });
|
|
1880
1829
|
}
|
|
1881
1830
|
}
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
const
|
|
1831
|
+
console.log(chalk12.yellow("\n \uCD5C\uB300 \uBC18\uBCF5 \uD69F\uC218 \uB3C4\uB2EC.\n"));
|
|
1832
|
+
}
|
|
1833
|
+
async function connectServer() {
|
|
1834
|
+
const { setServer: setServer2, setAuth: setAuth2 } = await Promise.resolve().then(() => (init_store(), store_exports));
|
|
1835
|
+
const { addEnvironment: addEnvironment2 } = await Promise.resolve().then(() => (init_store(), store_exports));
|
|
1836
|
+
console.log(chalk12.bold("\n XGEN \uC11C\uBC84 \uC5F0\uACB0\n"));
|
|
1837
|
+
const presets = [
|
|
1838
|
+
{ id: "hq", name: "\uBCF8\uC0AC", url: "https://xgen.x2bee.com", email: "admin@plateer.com" },
|
|
1839
|
+
{ id: "jeju", name: "\uC81C\uC8FC", url: "https://jeju-xgen.x2bee.com", email: "admin@plateer.com" },
|
|
1840
|
+
{ id: "lotte", name: "\uB86F\uB370\uBAB0", url: "https://lotteimall-xgen.x2bee.com" }
|
|
1841
|
+
];
|
|
1842
|
+
presets.forEach((p, i) => console.log(` ${chalk12.cyan(`${i + 1}.`)} ${p.name} ${chalk12.gray(p.url)}`));
|
|
1843
|
+
console.log(` ${chalk12.cyan("4.")} \uC9C1\uC811 \uC785\uB825`);
|
|
1844
|
+
console.log();
|
|
1845
|
+
const choice = await ask(chalk12.cyan(" \u276F "));
|
|
1846
|
+
let url;
|
|
1847
|
+
let email;
|
|
1848
|
+
const ci = parseInt(choice) - 1;
|
|
1849
|
+
if (ci >= 0 && ci < presets.length) {
|
|
1850
|
+
url = presets[ci].url;
|
|
1851
|
+
email = presets[ci].email;
|
|
1852
|
+
addEnvironment2({ ...presets[ci], description: presets[ci].name });
|
|
1853
|
+
} else {
|
|
1854
|
+
url = await ask(chalk12.white(" URL: "));
|
|
1855
|
+
if (!url) return;
|
|
1856
|
+
}
|
|
1857
|
+
setServer2(url);
|
|
1858
|
+
console.log(chalk12.green(` \u2713 ${url}
|
|
1859
|
+
`));
|
|
1860
|
+
const inputEmail = email || await ask(chalk12.white(" \uC774\uBA54\uC77C: "));
|
|
1861
|
+
const pw = await ask(chalk12.white(" \uBE44\uBC00\uBC88\uD638: "));
|
|
1862
|
+
if (!inputEmail || !pw) return;
|
|
1886
1863
|
try {
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1864
|
+
const { apiLogin: apiLogin2 } = await Promise.resolve().then(() => (init_auth(), auth_exports));
|
|
1865
|
+
const result = await apiLogin2(inputEmail, pw);
|
|
1866
|
+
if (result.success && result.access_token) {
|
|
1867
|
+
setAuth2({ accessToken: result.access_token, refreshToken: result.refresh_token ?? "", userId: result.user_id ?? "", username: result.username ?? "", isAdmin: false, expiresAt: null });
|
|
1868
|
+
console.log(chalk12.green(` \u2713 ${result.username} \uB85C\uADF8\uC778\uB428
|
|
1869
|
+
`));
|
|
1890
1870
|
} else {
|
|
1891
|
-
|
|
1871
|
+
console.log(chalk12.red(` \u2717 ${result.message}
|
|
1872
|
+
`));
|
|
1892
1873
|
}
|
|
1893
|
-
const output = execSync3(cmd, {
|
|
1894
|
-
encoding: "utf-8",
|
|
1895
|
-
timeout: 1e4,
|
|
1896
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
1897
|
-
});
|
|
1898
|
-
return output || "(empty)";
|
|
1899
1874
|
} catch (err) {
|
|
1900
|
-
|
|
1875
|
+
console.log(chalk12.red(` \u2717 ${err.message}
|
|
1876
|
+
`));
|
|
1901
1877
|
}
|
|
1902
1878
|
}
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
}
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1879
|
+
async function switchEnv() {
|
|
1880
|
+
const { getEnvironments: getEnvs, switchEnvironment: switchEnvironment2 } = await Promise.resolve().then(() => (init_store(), store_exports));
|
|
1881
|
+
const envs = getEnvs();
|
|
1882
|
+
if (!envs.length) {
|
|
1883
|
+
console.log(chalk12.gray("\n \uD658\uACBD \uC5C6\uC74C. /connect\uB85C \uBA3C\uC800 \uC5F0\uACB0\uD558\uC138\uC694.\n"));
|
|
1884
|
+
return;
|
|
1885
|
+
}
|
|
1886
|
+
const active = getActiveEnvironment();
|
|
1887
|
+
console.log();
|
|
1888
|
+
envs.forEach((e, i) => {
|
|
1889
|
+
const mark = e.id === active?.id ? chalk12.green("\u25CF ") : " ";
|
|
1890
|
+
console.log(` ${mark}${chalk12.cyan(`${i + 1}.`)} ${e.name} ${chalk12.gray(e.url)}`);
|
|
1891
|
+
});
|
|
1892
|
+
console.log();
|
|
1893
|
+
const ci = parseInt(await ask(chalk12.cyan(" \u276F "))) - 1;
|
|
1894
|
+
if (ci >= 0 && ci < envs.length) {
|
|
1895
|
+
switchEnvironment2(envs[ci].id);
|
|
1896
|
+
console.log(chalk12.green(` \u2713 ${envs[ci].name}
|
|
1897
|
+
`));
|
|
1918
1898
|
}
|
|
1919
|
-
return SANDBOX_DIR;
|
|
1920
1899
|
}
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
description: "\uC124\uCE58\uD560 \uD328\uD0A4\uC9C0 (npm \uB610\uB294 pip)"
|
|
1939
|
-
}
|
|
1940
|
-
},
|
|
1941
|
-
required: ["language", "code"]
|
|
1942
|
-
}
|
|
1900
|
+
function registerAgentCommand(program2) {
|
|
1901
|
+
program2.command("agent").description("OPEN XGEN AI \uC5D0\uC774\uC804\uD2B8").action(async () => {
|
|
1902
|
+
await agentRepl();
|
|
1903
|
+
});
|
|
1904
|
+
}
|
|
1905
|
+
var mcpManager;
|
|
1906
|
+
var init_agent = __esm({
|
|
1907
|
+
"src/commands/agent.ts"() {
|
|
1908
|
+
"use strict";
|
|
1909
|
+
init_store();
|
|
1910
|
+
init_llm();
|
|
1911
|
+
init_tools();
|
|
1912
|
+
init_xgen_api();
|
|
1913
|
+
init_client2();
|
|
1914
|
+
init_provider();
|
|
1915
|
+
init_ui();
|
|
1916
|
+
mcpManager = null;
|
|
1943
1917
|
}
|
|
1944
|
-
};
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1918
|
+
});
|
|
1919
|
+
|
|
1920
|
+
// src/dashboard/renderer.ts
|
|
1921
|
+
import chalk15 from "chalk";
|
|
1922
|
+
function clearScreen() {
|
|
1923
|
+
process.stdout.write("\x1B[2J\x1B[H");
|
|
1924
|
+
}
|
|
1925
|
+
function renderHeader(activeTab, tabs, env) {
|
|
1926
|
+
const w = W2();
|
|
1927
|
+
const title = chalk15.cyan.bold(" OPEN XGEN ");
|
|
1928
|
+
const envTag = env ? chalk15.gray(` \xB7 ${env}`) : "";
|
|
1929
|
+
const tabBar = tabs.map((t) => {
|
|
1930
|
+
if (t === activeTab) return chalk15.bgCyan.black(` ${t} `);
|
|
1931
|
+
return chalk15.gray(` ${t} `);
|
|
1932
|
+
}).join(chalk15.gray("\u2502"));
|
|
1933
|
+
console.log(chalk15.bgGray.black(" ".repeat(w)));
|
|
1934
|
+
console.log(chalk15.bgGray.black(`${title}${envTag}${" ".repeat(Math.max(0, w - stripAnsi(title + envTag).length))}`));
|
|
1935
|
+
console.log(chalk15.gray("\u2500".repeat(w)));
|
|
1936
|
+
console.log(tabBar);
|
|
1937
|
+
console.log(chalk15.gray("\u2500".repeat(w)));
|
|
1938
|
+
}
|
|
1939
|
+
function renderStatusBar(text) {
|
|
1940
|
+
const w = W2();
|
|
1941
|
+
const padded = ` ${text}${" ".repeat(Math.max(0, w - text.length - 1))}`;
|
|
1942
|
+
console.log(chalk15.gray("\u2500".repeat(w)));
|
|
1943
|
+
console.log(chalk15.bgGray.black(padded));
|
|
1944
|
+
}
|
|
1945
|
+
function renderList(items, selected, title, startRow) {
|
|
1946
|
+
if (title) console.log(chalk15.bold(` ${title}`));
|
|
1947
|
+
console.log();
|
|
1948
|
+
const pageSize = H() - 12;
|
|
1949
|
+
const start = Math.max(0, selected - pageSize + 3);
|
|
1950
|
+
const visible = items.slice(start, start + pageSize);
|
|
1951
|
+
visible.forEach((item, i) => {
|
|
1952
|
+
const idx = start + i;
|
|
1953
|
+
const cursor = idx === selected ? chalk15.cyan("\u25B8 ") : " ";
|
|
1954
|
+
const num = chalk15.gray(`${String(idx + 1).padStart(3)}.`);
|
|
1955
|
+
const tag = item.tag ? ` ${item.tag}` : "";
|
|
1956
|
+
const line = `${cursor}${num} ${item.label}${tag}`;
|
|
1957
|
+
if (idx === selected) {
|
|
1958
|
+
console.log(chalk15.white.bold(line));
|
|
1959
|
+
if (item.detail) console.log(chalk15.gray(` ${item.detail}`));
|
|
1984
1960
|
} else {
|
|
1985
|
-
|
|
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 {
|
|
2001
|
-
try {
|
|
2002
|
-
rmSync(runDir, { recursive: true, force: true });
|
|
2003
|
-
} catch {
|
|
1961
|
+
console.log(line);
|
|
2004
1962
|
}
|
|
1963
|
+
});
|
|
1964
|
+
if (items.length > pageSize) {
|
|
1965
|
+
console.log(chalk15.gray(`
|
|
1966
|
+
${start + 1}-${Math.min(start + pageSize, items.length)} / ${items.length}`));
|
|
2005
1967
|
}
|
|
2006
1968
|
}
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
}
|
|
2017
|
-
|
|
2018
|
-
const tool = toolMap.get(name);
|
|
2019
|
-
if (!tool) return `Unknown tool: ${name}`;
|
|
2020
|
-
return tool.execute(args);
|
|
1969
|
+
function renderPanel(title, lines) {
|
|
1970
|
+
const w = W2() - 4;
|
|
1971
|
+
console.log(chalk15.cyan(` \u250C${"\u2500".repeat(w)}\u2510`));
|
|
1972
|
+
console.log(chalk15.cyan(` \u2502 ${chalk15.bold(title)}${" ".repeat(Math.max(0, w - stripAnsi(title).length - 1))}\u2502`));
|
|
1973
|
+
console.log(chalk15.cyan(` \u251C${"\u2500".repeat(w)}\u2524`));
|
|
1974
|
+
for (const line of lines) {
|
|
1975
|
+
const clean = stripAnsi(line);
|
|
1976
|
+
const pad = Math.max(0, w - clean.length - 1);
|
|
1977
|
+
console.log(chalk15.cyan(` \u2502 `) + line + " ".repeat(pad) + chalk15.cyan("\u2502"));
|
|
1978
|
+
}
|
|
1979
|
+
console.log(chalk15.cyan(` \u2514${"\u2500".repeat(w)}\u2518`));
|
|
2021
1980
|
}
|
|
2022
|
-
function
|
|
2023
|
-
return
|
|
1981
|
+
function stripAnsi(str) {
|
|
1982
|
+
return str.replace(/\x1b\[[0-9;]*m/g, "");
|
|
2024
1983
|
}
|
|
1984
|
+
var W2, H;
|
|
1985
|
+
var init_renderer = __esm({
|
|
1986
|
+
"src/dashboard/renderer.ts"() {
|
|
1987
|
+
"use strict";
|
|
1988
|
+
W2 = () => Math.min(process.stdout.columns || 80, 100);
|
|
1989
|
+
H = () => Math.min(process.stdout.rows || 30, 40);
|
|
1990
|
+
}
|
|
1991
|
+
});
|
|
2025
1992
|
|
|
2026
|
-
// src/
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
1993
|
+
// src/dashboard/index.ts
|
|
1994
|
+
var dashboard_exports = {};
|
|
1995
|
+
__export(dashboard_exports, {
|
|
1996
|
+
dashboard: () => dashboard
|
|
1997
|
+
});
|
|
1998
|
+
import chalk16 from "chalk";
|
|
1999
|
+
import { createInterface as createInterface7 } from "readline";
|
|
2000
|
+
async function dashboard() {
|
|
2001
|
+
const state = {
|
|
2002
|
+
activeTab: 0,
|
|
2003
|
+
workflows: [],
|
|
2004
|
+
documents: [],
|
|
2005
|
+
selectedIdx: 0
|
|
2006
|
+
};
|
|
2007
|
+
await loadData(state);
|
|
2008
|
+
render(state);
|
|
2009
|
+
const rl = createInterface7({ input: process.stdin, output: process.stdout });
|
|
2010
|
+
if (process.stdin.isTTY) {
|
|
2011
|
+
process.stdin.setRawMode(true);
|
|
2012
|
+
process.stdin.resume();
|
|
2013
|
+
process.stdin.setEncoding("utf8");
|
|
2014
|
+
process.stdin.on("data", async (key) => {
|
|
2015
|
+
if (key === "") {
|
|
2016
|
+
cleanup(rl);
|
|
2017
|
+
process.exit(0);
|
|
2051
2018
|
}
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
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"]
|
|
2019
|
+
if (key === " ") {
|
|
2020
|
+
state.activeTab = (state.activeTab + 1) % TABS.length;
|
|
2021
|
+
state.selectedIdx = 0;
|
|
2022
|
+
render(state);
|
|
2023
|
+
return;
|
|
2065
2024
|
}
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
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
|
-
}
|
|
2025
|
+
if (key === "\x1B[Z") {
|
|
2026
|
+
state.activeTab = (state.activeTab - 1 + TABS.length) % TABS.length;
|
|
2027
|
+
state.selectedIdx = 0;
|
|
2028
|
+
render(state);
|
|
2029
|
+
return;
|
|
2078
2030
|
}
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
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"]
|
|
2031
|
+
if (key === "\x1B[A") {
|
|
2032
|
+
state.selectedIdx = Math.max(0, state.selectedIdx - 1);
|
|
2033
|
+
render(state);
|
|
2034
|
+
return;
|
|
2093
2035
|
}
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
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
|
-
}
|
|
2036
|
+
if (key === "\x1B[B") {
|
|
2037
|
+
const max = getCurrentListLength(state) - 1;
|
|
2038
|
+
state.selectedIdx = Math.min(max, state.selectedIdx + 1);
|
|
2039
|
+
render(state);
|
|
2040
|
+
return;
|
|
2114
2041
|
}
|
|
2115
|
-
|
|
2042
|
+
if (key === "\r") {
|
|
2043
|
+
await handleEnter(state, rl);
|
|
2044
|
+
return;
|
|
2045
|
+
}
|
|
2046
|
+
const num = parseInt(key);
|
|
2047
|
+
if (num >= 1 && num <= 5) {
|
|
2048
|
+
state.activeTab = num - 1;
|
|
2049
|
+
state.selectedIdx = 0;
|
|
2050
|
+
render(state);
|
|
2051
|
+
return;
|
|
2052
|
+
}
|
|
2053
|
+
if (key === "c") {
|
|
2054
|
+
state.activeTab = 0;
|
|
2055
|
+
render(state);
|
|
2056
|
+
return;
|
|
2057
|
+
}
|
|
2058
|
+
if (key === "w") {
|
|
2059
|
+
state.activeTab = 1;
|
|
2060
|
+
render(state);
|
|
2061
|
+
return;
|
|
2062
|
+
}
|
|
2063
|
+
if (key === "d") {
|
|
2064
|
+
state.activeTab = 2;
|
|
2065
|
+
render(state);
|
|
2066
|
+
return;
|
|
2067
|
+
}
|
|
2068
|
+
if (key === "o") {
|
|
2069
|
+
state.activeTab = 3;
|
|
2070
|
+
render(state);
|
|
2071
|
+
return;
|
|
2072
|
+
}
|
|
2073
|
+
if (key === "s") {
|
|
2074
|
+
state.activeTab = 4;
|
|
2075
|
+
render(state);
|
|
2076
|
+
return;
|
|
2077
|
+
}
|
|
2078
|
+
if (key === "r") {
|
|
2079
|
+
await loadData(state);
|
|
2080
|
+
render(state);
|
|
2081
|
+
return;
|
|
2082
|
+
}
|
|
2083
|
+
if (key === "q") {
|
|
2084
|
+
cleanup(rl);
|
|
2085
|
+
process.exit(0);
|
|
2086
|
+
}
|
|
2087
|
+
});
|
|
2088
|
+
} else {
|
|
2089
|
+
cleanup(rl);
|
|
2090
|
+
await agentRepl();
|
|
2116
2091
|
}
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2092
|
+
}
|
|
2093
|
+
function render(state) {
|
|
2094
|
+
clearScreen();
|
|
2095
|
+
const env = getActiveEnvironment();
|
|
2120
2096
|
const auth = getAuth();
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
}
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
}
|
|
2143
|
-
} catch (err) {
|
|
2144
|
-
return `XGEN API \uC624\uB958: ${err.message}`;
|
|
2097
|
+
const server = getServer();
|
|
2098
|
+
const envLabel = env?.name ?? (server ? server.replace("https://", "") : "\uBBF8\uC5F0\uACB0");
|
|
2099
|
+
const userLabel = auth ? `${auth.username}@${envLabel}` : envLabel;
|
|
2100
|
+
renderHeader(TABS[state.activeTab], TABS, userLabel);
|
|
2101
|
+
console.log();
|
|
2102
|
+
switch (state.activeTab) {
|
|
2103
|
+
case 0:
|
|
2104
|
+
renderChatTab();
|
|
2105
|
+
break;
|
|
2106
|
+
case 1:
|
|
2107
|
+
renderWorkflowTab(state);
|
|
2108
|
+
break;
|
|
2109
|
+
case 2:
|
|
2110
|
+
renderDocTab(state);
|
|
2111
|
+
break;
|
|
2112
|
+
case 3:
|
|
2113
|
+
renderOntologyTab();
|
|
2114
|
+
break;
|
|
2115
|
+
case 4:
|
|
2116
|
+
renderSettingsTab();
|
|
2117
|
+
break;
|
|
2145
2118
|
}
|
|
2119
|
+
const provider = getDefaultProvider();
|
|
2120
|
+
const statusText = `${provider?.name ?? "AI \uBBF8\uC124\uC815"} \xB7 ${provider?.model ?? ""} \u2502 Tab:\uC804\uD658 \u2191\u2193:\uC120\uD0DD Enter:\uC2E4\uD589 r:\uC0C8\uB85C\uACE0\uCE68 q:\uC885\uB8CC`;
|
|
2121
|
+
renderStatusBar(statusText);
|
|
2146
2122
|
}
|
|
2147
|
-
function
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
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
|
|
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);
|
|
2123
|
+
function renderChatTab() {
|
|
2124
|
+
console.log(chalk16.bold(" AI \uC5D0\uC774\uC804\uD2B8"));
|
|
2125
|
+
console.log();
|
|
2126
|
+
console.log(chalk16.gray(" Enter\uB97C \uB20C\uB7EC AI \uCC44\uD305 \uBAA8\uB4DC\uB85C \uC9C4\uC785\uD569\uB2C8\uB2E4."));
|
|
2127
|
+
console.log(chalk16.gray(" \uCC44\uD305\uC5D0\uC11C \uC6CC\uD06C\uD50C\uB85C\uC6B0 \uC2E4\uD589, \uD30C\uC77C \uD3B8\uC9D1, \uCF54\uB4DC \uC2E4\uD589 \uBAA8\uB450 \uAC00\uB2A5\uD569\uB2C8\uB2E4."));
|
|
2128
|
+
console.log();
|
|
2129
|
+
console.log(chalk16.gray(" \uC608\uC2DC:"));
|
|
2130
|
+
console.log(chalk16.white(' "\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uBAA9\uB85D \uBCF4\uC5EC\uC918"'));
|
|
2131
|
+
console.log(chalk16.white(' "\uC7AC\uC9C1\uC99D\uBA85\uC11C \uC6CC\uD06C\uD50C\uB85C\uC6B0 \uC2E4\uD589\uD574\uC918"'));
|
|
2132
|
+
console.log(chalk16.white(' "\uC774 \uD3F4\uB354\uC5D0 \uC788\uB294 \uD30C\uC77C \uBB50 \uC788\uC5B4?"'));
|
|
2133
|
+
console.log(chalk16.white(' "Python\uC73C\uB85C fibonacci \uD568\uC218 \uB9CC\uB4E4\uC5B4\uC918"'));
|
|
2134
|
+
console.log();
|
|
2176
2135
|
}
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
\uB178\uB4DC: ${nodes}\uAC1C
|
|
2185
|
-
\uC5E3\uC9C0: ${edges}\uAC1C`;
|
|
2136
|
+
function renderWorkflowTab(state) {
|
|
2137
|
+
if (state.workflows.length === 0) {
|
|
2138
|
+
console.log(chalk16.gray(" \uC11C\uBC84 \uBBF8\uC5F0\uACB0 \uB610\uB294 \uC6CC\uD06C\uD50C\uB85C\uC6B0 \uC5C6\uC74C"));
|
|
2139
|
+
console.log(chalk16.gray(" s\uD0A4 \u2192 \uC124\uC815\uC5D0\uC11C \uC11C\uBC84 \uC5F0\uACB0"));
|
|
2140
|
+
return;
|
|
2141
|
+
}
|
|
2142
|
+
renderList(state.workflows, state.selectedIdx, `\uC6CC\uD06C\uD50C\uB85C\uC6B0 (${state.workflows.length}\uAC1C)`);
|
|
2186
2143
|
}
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
).join("\n");
|
|
2144
|
+
function renderDocTab(state) {
|
|
2145
|
+
if (state.documents.length === 0) {
|
|
2146
|
+
console.log(chalk16.gray(" \uC11C\uBC84 \uBBF8\uC5F0\uACB0 \uB610\uB294 \uBB38\uC11C \uC5C6\uC74C"));
|
|
2147
|
+
return;
|
|
2148
|
+
}
|
|
2149
|
+
renderList(state.documents, state.selectedIdx, `\uBB38\uC11C (${state.documents.length}\uAC1C)`);
|
|
2194
2150
|
}
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
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.";
|
|
2151
|
+
function renderOntologyTab() {
|
|
2152
|
+
console.log(chalk16.bold(" \uC628\uD1A8\uB85C\uC9C0 (GraphRAG)"));
|
|
2153
|
+
console.log();
|
|
2154
|
+
console.log(chalk16.gray(" Enter\uB97C \uB20C\uB7EC \uC628\uD1A8\uB85C\uC9C0 \uC9C8\uC758 \uBAA8\uB4DC\uB85C \uC9C4\uC785\uD569\uB2C8\uB2E4."));
|
|
2155
|
+
console.log(chalk16.gray(" \uC9C0\uC2DD \uADF8\uB798\uD504 \uAE30\uBC18 \uC9C8\uBB38-\uB2F5\uBCC0\uC744 \uC218\uD589\uD569\uB2C8\uB2E4."));
|
|
2156
|
+
console.log();
|
|
2205
2157
|
}
|
|
2206
|
-
|
|
2158
|
+
function renderSettingsTab() {
|
|
2159
|
+
const provider = getDefaultProvider();
|
|
2207
2160
|
const server = getServer();
|
|
2208
2161
|
const auth = getAuth();
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2162
|
+
const env = getActiveEnvironment();
|
|
2163
|
+
const lines = [
|
|
2164
|
+
`\uD504\uB85C\uBC14\uC774\uB354: ${provider ? `${provider.name} \xB7 ${provider.model}` : chalk16.red("\uBBF8\uC124\uC815")}`,
|
|
2165
|
+
`\uC11C\uBC84: ${server ?? chalk16.red("\uBBF8\uC5F0\uACB0")}`,
|
|
2166
|
+
`\uC0AC\uC6A9\uC790: ${auth?.username ?? "-"}`,
|
|
2167
|
+
`\uD658\uACBD: ${env?.name ?? "-"}`
|
|
2168
|
+
];
|
|
2169
|
+
renderPanel("\uD604\uC7AC \uC124\uC815", lines);
|
|
2170
|
+
console.log();
|
|
2171
|
+
console.log(chalk16.gray(" Enter \u2192 AI \uCC44\uD305\uC5D0\uC11C /connect, /provider, /env \uC0AC\uC6A9"));
|
|
2212
2172
|
}
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
).join("\n");
|
|
2173
|
+
function getCurrentListLength(state) {
|
|
2174
|
+
switch (state.activeTab) {
|
|
2175
|
+
case 1:
|
|
2176
|
+
return state.workflows.length;
|
|
2177
|
+
case 2:
|
|
2178
|
+
return state.documents.length;
|
|
2179
|
+
default:
|
|
2180
|
+
return 0;
|
|
2181
|
+
}
|
|
2223
2182
|
}
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
var McpClient = class {
|
|
2231
|
-
process = null;
|
|
2232
|
-
requestId = 0;
|
|
2233
|
-
pending = /* @__PURE__ */ new Map();
|
|
2234
|
-
serverName;
|
|
2235
|
-
config;
|
|
2236
|
-
tools = [];
|
|
2237
|
-
constructor(serverName, config) {
|
|
2238
|
-
this.serverName = serverName;
|
|
2239
|
-
this.config = config;
|
|
2240
|
-
}
|
|
2241
|
-
async start() {
|
|
2242
|
-
this.process = spawn(this.config.command, this.config.args ?? [], {
|
|
2243
|
-
stdio: ["pipe", "pipe", "pipe"],
|
|
2244
|
-
env: { ...process.env, ...this.config.env }
|
|
2245
|
-
});
|
|
2246
|
-
const rl = createInterface4({ input: this.process.stdout });
|
|
2247
|
-
rl.on("line", (line) => {
|
|
2248
|
-
try {
|
|
2249
|
-
const msg = JSON.parse(line);
|
|
2250
|
-
if (msg.id !== void 0 && this.pending.has(msg.id)) {
|
|
2251
|
-
const p = this.pending.get(msg.id);
|
|
2252
|
-
this.pending.delete(msg.id);
|
|
2253
|
-
if (msg.error) {
|
|
2254
|
-
p.reject(new Error(msg.error.message));
|
|
2255
|
-
} else {
|
|
2256
|
-
p.resolve(msg.result);
|
|
2257
|
-
}
|
|
2258
|
-
}
|
|
2259
|
-
} catch {
|
|
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
|
-
}
|
|
2290
|
-
});
|
|
2291
|
-
this.process?.stdin?.write(JSON.stringify(request) + "\n");
|
|
2292
|
-
});
|
|
2183
|
+
async function handleEnter(state, rl) {
|
|
2184
|
+
if (state.activeTab === 0 || state.activeTab === 3 || state.activeTab === 4) {
|
|
2185
|
+
cleanup(rl);
|
|
2186
|
+
await agentRepl();
|
|
2187
|
+
await dashboard();
|
|
2188
|
+
return;
|
|
2293
2189
|
}
|
|
2294
|
-
|
|
2295
|
-
const
|
|
2296
|
-
|
|
2297
|
-
|
|
2190
|
+
if (state.activeTab === 1 && state.workflows.length > 0) {
|
|
2191
|
+
const selected = state.workflows[state.selectedIdx];
|
|
2192
|
+
cleanup(rl);
|
|
2193
|
+
console.log(chalk16.green(`
|
|
2194
|
+
\u2713 ${selected.label} \uC120\uD0DD\uB428
|
|
2195
|
+
`));
|
|
2196
|
+
await agentRepl();
|
|
2197
|
+
await dashboard();
|
|
2198
|
+
return;
|
|
2298
2199
|
}
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2200
|
+
}
|
|
2201
|
+
async function loadData(state) {
|
|
2202
|
+
const server = getServer();
|
|
2203
|
+
const auth = getAuth();
|
|
2204
|
+
if (!server || !auth) return;
|
|
2205
|
+
try {
|
|
2206
|
+
const { getWorkflowListDetail: getWorkflowListDetail2 } = await Promise.resolve().then(() => (init_workflow(), workflow_exports));
|
|
2207
|
+
const wfs = await getWorkflowListDetail2();
|
|
2208
|
+
state.workflows = wfs.map((w) => {
|
|
2209
|
+
const deployed = w.is_deployed;
|
|
2210
|
+
return {
|
|
2211
|
+
label: w.workflow_name,
|
|
2212
|
+
detail: (w.workflow_id ?? w.id ?? "").toString(),
|
|
2213
|
+
tag: deployed ? chalk16.green("[\uBC30\uD3EC]") : void 0
|
|
2214
|
+
};
|
|
2215
|
+
});
|
|
2216
|
+
} catch {
|
|
2302
2217
|
}
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
}
|
|
2218
|
+
try {
|
|
2219
|
+
const { listDocuments: listDocuments2 } = await Promise.resolve().then(() => (init_document(), document_exports));
|
|
2220
|
+
const docs = await listDocuments2();
|
|
2221
|
+
state.documents = docs.map((d) => ({
|
|
2222
|
+
label: d.file_name ?? d.name ?? "-",
|
|
2223
|
+
detail: d.file_type ?? "-",
|
|
2224
|
+
tag: d.status ? chalk16.gray(`[${d.status}]`) : void 0
|
|
2311
2225
|
}));
|
|
2226
|
+
} catch {
|
|
2312
2227
|
}
|
|
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
|
-
}
|
|
2331
|
-
}
|
|
2332
|
-
}
|
|
2333
|
-
return null;
|
|
2334
2228
|
}
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
}
|
|
2349
|
-
}
|
|
2350
|
-
getAllTools() {
|
|
2351
|
-
const tools2 = [];
|
|
2352
|
-
for (const client2 of this.clients.values()) {
|
|
2353
|
-
tools2.push(...client2.getOpenAITools());
|
|
2354
|
-
}
|
|
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()];
|
|
2229
|
+
function cleanup(rl) {
|
|
2230
|
+
if (process.stdin.isTTY) process.stdin.setRawMode(false);
|
|
2231
|
+
rl.close();
|
|
2232
|
+
clearScreen();
|
|
2233
|
+
}
|
|
2234
|
+
var TABS;
|
|
2235
|
+
var init_dashboard = __esm({
|
|
2236
|
+
"src/dashboard/index.ts"() {
|
|
2237
|
+
"use strict";
|
|
2238
|
+
init_renderer();
|
|
2239
|
+
init_store();
|
|
2240
|
+
init_agent();
|
|
2241
|
+
TABS = ["\u{1F4AC} Chat", "\u{1F4CB} Workflows", "\u{1F4C4} Documents", "\u{1F50D} Ontology", "\u2699 Settings"];
|
|
2380
2242
|
}
|
|
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 += `
|
|
2243
|
+
});
|
|
2404
2244
|
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
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 += `
|
|
2245
|
+
// src/index.ts
|
|
2246
|
+
import { Command } from "commander";
|
|
2247
|
+
import chalk17 from "chalk";
|
|
2412
2248
|
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
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();
|
|
2431
|
-
try {
|
|
2432
|
-
await mcpManager.startAll(mcpConfig);
|
|
2433
|
-
if (mcpManager.serverCount > 0) allTools.push(...mcpManager.getAllTools());
|
|
2434
|
-
} catch {
|
|
2249
|
+
// src/commands/config.ts
|
|
2250
|
+
init_store();
|
|
2251
|
+
init_client();
|
|
2252
|
+
init_format();
|
|
2253
|
+
import chalk2 from "chalk";
|
|
2254
|
+
function registerConfigCommand(program2) {
|
|
2255
|
+
const config = program2.command("config").description("XGEN CLI \uC124\uC815 \uAD00\uB9AC");
|
|
2256
|
+
config.command("set-server <url>").description("XGEN \uC11C\uBC84 URL \uC124\uC815").action((url) => {
|
|
2257
|
+
if (!url.startsWith("http://") && !url.startsWith("https://")) {
|
|
2258
|
+
printError("URL\uC740 http:// \uB610\uB294 https://\uB85C \uC2DC\uC791\uD574\uC57C \uD569\uB2C8\uB2E4");
|
|
2259
|
+
process.exit(1);
|
|
2435
2260
|
}
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
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);
|
|
2457
|
-
});
|
|
2458
|
-
while (true) {
|
|
2459
|
-
const input = await askUser();
|
|
2460
|
-
if (!input) continue;
|
|
2461
|
-
if (input === "/exit" || input === "exit") {
|
|
2462
|
-
console.log(chalk12.gray("\n \u{1F44B}\n"));
|
|
2463
|
-
mcpManager?.stopAll();
|
|
2464
|
-
rl.close();
|
|
2465
|
-
break;
|
|
2466
|
-
}
|
|
2467
|
-
if (input === "/help") {
|
|
2468
|
-
console.log(`
|
|
2469
|
-
${chalk12.bold("\uC2AC\uB798\uC2DC \uCEE4\uB9E8\uB4DC")}
|
|
2470
|
-
${chalk12.cyan("/connect")} XGEN \uC11C\uBC84 \uC5F0\uACB0 + \uB85C\uADF8\uC778
|
|
2471
|
-
${chalk12.cyan("/env")} \uD658\uACBD \uC804\uD658 (\uBCF8\uC0AC/\uC81C\uC8FC/\uB86F\uB370\uBAB0)
|
|
2472
|
-
${chalk12.cyan("/provider")} \uD504\uB85C\uBC14\uC774\uB354 \uBCC0\uACBD
|
|
2473
|
-
${chalk12.cyan("/tools")} \uC0AC\uC6A9 \uAC00\uB2A5\uD55C \uB3C4\uAD6C \uBAA9\uB85D
|
|
2474
|
-
${chalk12.cyan("/status")} \uD604\uC7AC \uC5F0\uACB0 \uC0C1\uD0DC
|
|
2475
|
-
${chalk12.cyan("/clear")} \uB300\uD654 \uCD08\uAE30\uD654
|
|
2476
|
-
${chalk12.cyan("/exit")} \uC885\uB8CC
|
|
2477
|
-
`);
|
|
2478
|
-
continue;
|
|
2479
|
-
}
|
|
2480
|
-
if (input === "/clear") {
|
|
2481
|
-
messages.length = 0;
|
|
2482
|
-
messages.push({ role: "system", content: buildSystemPrompt() });
|
|
2483
|
-
console.log(chalk12.gray(" \uB300\uD654 \uCD08\uAE30\uD654\uB428.\n"));
|
|
2484
|
-
continue;
|
|
2261
|
+
setServer(url);
|
|
2262
|
+
resetClient();
|
|
2263
|
+
printSuccess(`\uC11C\uBC84 \uC124\uC815 \uC644\uB8CC: ${chalk2.underline(url)}`);
|
|
2264
|
+
});
|
|
2265
|
+
config.command("get-server").description("\uD604\uC7AC \uC124\uC815\uB41C \uC11C\uBC84 URL \uD655\uC778").action(() => {
|
|
2266
|
+
const server = getServer();
|
|
2267
|
+
if (server) {
|
|
2268
|
+
console.log(server);
|
|
2269
|
+
} else {
|
|
2270
|
+
printError("\uC11C\uBC84\uAC00 \uC124\uC815\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4");
|
|
2271
|
+
console.log(" \uC124\uC815: xgen config set-server <url>");
|
|
2485
2272
|
}
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2273
|
+
});
|
|
2274
|
+
config.command("list").description("\uC804\uCCB4 \uC124\uC815 \uD655\uC778").action(() => {
|
|
2275
|
+
const cfg = getConfig();
|
|
2276
|
+
console.log(chalk2.bold("\nXGEN CLI \uC124\uC815"));
|
|
2277
|
+
console.log(chalk2.gray("\u2500".repeat(40)));
|
|
2278
|
+
printKeyValue("\uC11C\uBC84", cfg.server);
|
|
2279
|
+
printKeyValue("\uAE30\uBCF8 \uC6CC\uD06C\uD50C\uB85C\uC6B0", cfg.defaultWorkflow);
|
|
2280
|
+
printKeyValue("\uD14C\uB9C8", cfg.theme);
|
|
2281
|
+
printKeyValue("\uC2A4\uD2B8\uB9BC \uB85C\uADF8", String(cfg.streamLogs));
|
|
2282
|
+
console.log();
|
|
2283
|
+
});
|
|
2284
|
+
config.command("set <key> <value>").description("\uC124\uC815 \uAC12 \uBCC0\uACBD").action((key, value) => {
|
|
2285
|
+
const allowedKeys = ["defaultWorkflow", "theme", "streamLogs"];
|
|
2286
|
+
if (!allowedKeys.includes(key)) {
|
|
2287
|
+
printError(`\uC54C \uC218 \uC5C6\uB294 \uC124\uC815 \uD0A4: ${key}`);
|
|
2288
|
+
console.log(` \uC0AC\uC6A9 \uAC00\uB2A5: ${allowedKeys.join(", ")}`);
|
|
2289
|
+
process.exit(1);
|
|
2500
2290
|
}
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2291
|
+
const parsed = key === "streamLogs" ? value === "true" : value;
|
|
2292
|
+
setConfig({ [key]: parsed });
|
|
2293
|
+
printSuccess(`${key} = ${value}`);
|
|
2294
|
+
});
|
|
2295
|
+
}
|
|
2296
|
+
|
|
2297
|
+
// src/commands/login.ts
|
|
2298
|
+
init_auth();
|
|
2299
|
+
init_store();
|
|
2300
|
+
init_format();
|
|
2301
|
+
import chalk3 from "chalk";
|
|
2302
|
+
import { createInterface } from "readline";
|
|
2303
|
+
function prompt(question, hidden = false) {
|
|
2304
|
+
return new Promise((resolve) => {
|
|
2305
|
+
const rl = createInterface({
|
|
2306
|
+
input: process.stdin,
|
|
2307
|
+
output: process.stdout
|
|
2308
|
+
});
|
|
2309
|
+
if (hidden) {
|
|
2310
|
+
process.stdout.write(question);
|
|
2311
|
+
const stdin = process.stdin;
|
|
2312
|
+
const wasRaw = stdin.isRaw;
|
|
2313
|
+
if (stdin.isTTY) stdin.setRawMode(true);
|
|
2314
|
+
let password = "";
|
|
2315
|
+
const onData = (ch) => {
|
|
2316
|
+
const c = ch.toString("utf8");
|
|
2317
|
+
if (c === "\n" || c === "\r" || c === "") {
|
|
2318
|
+
if (stdin.isTTY) stdin.setRawMode(wasRaw ?? false);
|
|
2319
|
+
stdin.removeListener("data", onData);
|
|
2320
|
+
process.stdout.write("\n");
|
|
2321
|
+
rl.close();
|
|
2322
|
+
resolve(password);
|
|
2323
|
+
} else if (c === "") {
|
|
2324
|
+
process.exit(0);
|
|
2325
|
+
} else if (c === "\x7F" || c === "\b") {
|
|
2326
|
+
if (password.length > 0) {
|
|
2327
|
+
password = password.slice(0, -1);
|
|
2328
|
+
process.stdout.write("\b \b");
|
|
2329
|
+
}
|
|
2330
|
+
} else {
|
|
2331
|
+
password += c;
|
|
2332
|
+
process.stdout.write("*");
|
|
2333
|
+
}
|
|
2334
|
+
};
|
|
2335
|
+
stdin.on("data", onData);
|
|
2336
|
+
} else {
|
|
2337
|
+
rl.question(question, (answer) => {
|
|
2338
|
+
rl.close();
|
|
2339
|
+
resolve(answer.trim());
|
|
2340
|
+
});
|
|
2510
2341
|
}
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2342
|
+
});
|
|
2343
|
+
}
|
|
2344
|
+
function registerLoginCommand(program2) {
|
|
2345
|
+
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) => {
|
|
2346
|
+
const server = requireServer();
|
|
2347
|
+
printHeader("XGEN Login");
|
|
2348
|
+
console.log(chalk3.gray(`\uC11C\uBC84: ${server}
|
|
2349
|
+
`));
|
|
2350
|
+
let email = opts.email;
|
|
2351
|
+
let password = opts.password;
|
|
2352
|
+
if (!email) {
|
|
2353
|
+
email = await prompt(chalk3.white("\uC774\uBA54\uC77C: "));
|
|
2515
2354
|
}
|
|
2516
|
-
if (
|
|
2517
|
-
await
|
|
2518
|
-
messages[0] = { role: "system", content: buildSystemPrompt() };
|
|
2519
|
-
continue;
|
|
2355
|
+
if (!password) {
|
|
2356
|
+
password = await prompt(chalk3.white("\uBE44\uBC00\uBC88\uD638: "), true);
|
|
2520
2357
|
}
|
|
2521
|
-
if (
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
console.log(chalk12.gray(" \uD504\uB85C\uBC14\uC774\uB354 \uBCC0\uACBD\uB428. /exit \uD6C4 \uC7AC\uC2DC\uC791\uD558\uC138\uC694.\n"));
|
|
2525
|
-
continue;
|
|
2358
|
+
if (!email || !password) {
|
|
2359
|
+
printError("\uC774\uBA54\uC77C\uACFC \uBE44\uBC00\uBC88\uD638\uB97C \uBAA8\uB450 \uC785\uB825\uD558\uC138\uC694");
|
|
2360
|
+
process.exit(1);
|
|
2526
2361
|
}
|
|
2527
|
-
messages.push({ role: "user", content: input });
|
|
2528
2362
|
try {
|
|
2529
|
-
await
|
|
2363
|
+
const result = await apiLogin(email, password);
|
|
2364
|
+
if (result.success && result.access_token) {
|
|
2365
|
+
setAuth({
|
|
2366
|
+
accessToken: result.access_token,
|
|
2367
|
+
refreshToken: result.refresh_token ?? "",
|
|
2368
|
+
userId: result.user_id ?? "",
|
|
2369
|
+
username: result.username ?? "",
|
|
2370
|
+
isAdmin: false,
|
|
2371
|
+
expiresAt: null
|
|
2372
|
+
});
|
|
2373
|
+
console.log();
|
|
2374
|
+
printSuccess(`\uB85C\uADF8\uC778 \uC131\uACF5! ${chalk3.bold(result.username ?? email)}`);
|
|
2375
|
+
} else {
|
|
2376
|
+
printError(result.message || "\uB85C\uADF8\uC778 \uC2E4\uD328");
|
|
2377
|
+
process.exit(1);
|
|
2378
|
+
}
|
|
2530
2379
|
} catch (err) {
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2380
|
+
const msg = err?.response?.data?.message ?? err?.response?.data?.detail ?? err.message;
|
|
2381
|
+
printError(`\uB85C\uADF8\uC778 \uC2E4\uD328: ${msg}`);
|
|
2382
|
+
process.exit(1);
|
|
2534
2383
|
}
|
|
2535
|
-
}
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
process.
|
|
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 });
|
|
2550
|
-
return;
|
|
2384
|
+
});
|
|
2385
|
+
program2.command("logout").description("\uB85C\uADF8\uC544\uC6C3").action(async () => {
|
|
2386
|
+
const { clearAuth: clearAuth2 } = await Promise.resolve().then(() => (init_store(), store_exports));
|
|
2387
|
+
clearAuth2();
|
|
2388
|
+
printSuccess("\uB85C\uADF8\uC544\uC6C3 \uC644\uB8CC");
|
|
2389
|
+
});
|
|
2390
|
+
program2.command("whoami").description("\uD604\uC7AC \uB85C\uADF8\uC778\uB41C \uC0AC\uC6A9\uC790 \uC815\uBCF4").action(async () => {
|
|
2391
|
+
const auth = getAuth();
|
|
2392
|
+
if (!auth) {
|
|
2393
|
+
printError("\uB85C\uADF8\uC778\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. xgen login \uC2E4\uD589\uD558\uC138\uC694");
|
|
2394
|
+
process.exit(1);
|
|
2551
2395
|
}
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
}))
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
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);
|
|
2396
|
+
const server = requireServer();
|
|
2397
|
+
console.log(chalk3.bold("\n\uD604\uC7AC \uC0AC\uC6A9\uC790"));
|
|
2398
|
+
console.log(chalk3.gray("\u2500".repeat(30)));
|
|
2399
|
+
console.log(` ${chalk3.gray("\uC11C\uBC84:")} ${server}`);
|
|
2400
|
+
console.log(` ${chalk3.gray("\uC0AC\uC6A9\uC790:")} ${chalk3.bold(auth.username)}`);
|
|
2401
|
+
console.log(` ${chalk3.gray("User ID:")} ${auth.userId}`);
|
|
2402
|
+
try {
|
|
2403
|
+
const { apiValidate: apiValidate2 } = await Promise.resolve().then(() => (init_auth(), auth_exports));
|
|
2404
|
+
const result = await apiValidate2(auth.accessToken);
|
|
2405
|
+
if (result.valid) {
|
|
2406
|
+
console.log(` ${chalk3.gray("\uC0C1\uD0DC:")} ${chalk3.green("\uD65C\uC131")}`);
|
|
2407
|
+
if (result.is_admin) {
|
|
2408
|
+
console.log(` ${chalk3.gray("\uAD8C\uD55C:")} ${chalk3.yellow("\uAD00\uB9AC\uC790")}`);
|
|
2409
|
+
}
|
|
2410
|
+
if (result.user_type) {
|
|
2411
|
+
console.log(` ${chalk3.gray("\uC720\uD615:")} ${result.user_type}`);
|
|
2412
|
+
}
|
|
2578
2413
|
} else {
|
|
2579
|
-
|
|
2414
|
+
console.log(` ${chalk3.gray("\uC0C1\uD0DC:")} ${chalk3.red("\uD1A0\uD070 \uB9CC\uB8CC")}`);
|
|
2580
2415
|
}
|
|
2581
|
-
|
|
2582
|
-
|
|
2416
|
+
} catch {
|
|
2417
|
+
console.log(` ${chalk3.gray("\uC0C1\uD0DC:")} ${chalk3.yellow("\uAC80\uC99D \uBD88\uAC00 (\uC11C\uBC84 \uC5F0\uACB0 \uC2E4\uD328)")}`);
|
|
2583
2418
|
}
|
|
2419
|
+
console.log();
|
|
2420
|
+
});
|
|
2421
|
+
}
|
|
2422
|
+
|
|
2423
|
+
// src/commands/workflow/list.ts
|
|
2424
|
+
init_store();
|
|
2425
|
+
init_workflow();
|
|
2426
|
+
init_format();
|
|
2427
|
+
import chalk4 from "chalk";
|
|
2428
|
+
async function workflowList(opts) {
|
|
2429
|
+
requireAuth();
|
|
2430
|
+
try {
|
|
2431
|
+
if (opts.detail) {
|
|
2432
|
+
const workflows = await getWorkflowListDetail();
|
|
2433
|
+
if (!workflows || workflows.length === 0) {
|
|
2434
|
+
console.log(chalk4.yellow("\n\uC6CC\uD06C\uD50C\uB85C\uC6B0\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.\n"));
|
|
2435
|
+
return;
|
|
2436
|
+
}
|
|
2437
|
+
printHeader(`\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uBAA9\uB85D (${workflows.length}\uAC1C)`);
|
|
2438
|
+
console.log();
|
|
2439
|
+
printTable(
|
|
2440
|
+
["#", "ID", "\uC774\uB984", "\uBC30\uD3EC", "\uC5C5\uB370\uC774\uD2B8"],
|
|
2441
|
+
workflows.map((w, i) => [
|
|
2442
|
+
String(i + 1),
|
|
2443
|
+
(w.workflow_id ?? w.id ?? "-").slice(0, 12),
|
|
2444
|
+
truncate(w.workflow_name ?? "-", 30),
|
|
2445
|
+
w.is_deployed ? chalk4.green("\uBC30\uD3EC\uB428") : chalk4.gray("\uBBF8\uBC30\uD3EC"),
|
|
2446
|
+
formatDate(w.updated_at)
|
|
2447
|
+
])
|
|
2448
|
+
);
|
|
2449
|
+
} else {
|
|
2450
|
+
const workflows = await listWorkflows();
|
|
2451
|
+
if (!workflows || workflows.length === 0) {
|
|
2452
|
+
console.log(chalk4.yellow("\n\uC6CC\uD06C\uD50C\uB85C\uC6B0\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.\n"));
|
|
2453
|
+
return;
|
|
2454
|
+
}
|
|
2455
|
+
printHeader(`\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uBAA9\uB85D (${workflows.length}\uAC1C)`);
|
|
2456
|
+
console.log();
|
|
2457
|
+
printTable(
|
|
2458
|
+
["#", "ID", "\uC774\uB984"],
|
|
2459
|
+
workflows.map((w, i) => [
|
|
2460
|
+
String(i + 1),
|
|
2461
|
+
(w.workflow_id ?? w.id ?? "-").slice(0, 12),
|
|
2462
|
+
w.workflow_name ?? "-"
|
|
2463
|
+
])
|
|
2464
|
+
);
|
|
2465
|
+
}
|
|
2466
|
+
console.log();
|
|
2467
|
+
} catch (err) {
|
|
2468
|
+
const msg = err.message;
|
|
2469
|
+
printError(`\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uBAA9\uB85D \uC870\uD68C \uC2E4\uD328: ${msg}`);
|
|
2470
|
+
process.exit(1);
|
|
2584
2471
|
}
|
|
2585
|
-
console.log(chalk12.yellow("\n \uCD5C\uB300 \uBC18\uBCF5 \uD69F\uC218 \uB3C4\uB2EC.\n"));
|
|
2586
2472
|
}
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2473
|
+
|
|
2474
|
+
// src/commands/workflow/info.ts
|
|
2475
|
+
init_store();
|
|
2476
|
+
init_workflow();
|
|
2477
|
+
init_format();
|
|
2478
|
+
import chalk5 from "chalk";
|
|
2479
|
+
async function workflowInfo(workflowId) {
|
|
2480
|
+
requireAuth();
|
|
2481
|
+
try {
|
|
2482
|
+
const detail = await getWorkflowDetail(workflowId);
|
|
2483
|
+
printHeader(`\uC6CC\uD06C\uD50C\uB85C\uC6B0: ${detail.workflow_name ?? workflowId}`);
|
|
2484
|
+
console.log();
|
|
2485
|
+
printKeyValue("ID", detail.id);
|
|
2486
|
+
printKeyValue("\uC774\uB984", detail.workflow_name);
|
|
2487
|
+
printKeyValue("\uC124\uBA85", detail.description ?? "(\uC5C6\uC74C)");
|
|
2488
|
+
if (detail.nodes && Array.isArray(detail.nodes)) {
|
|
2489
|
+
console.log();
|
|
2490
|
+
console.log(chalk5.bold(" \uB178\uB4DC \uAD6C\uC131:"));
|
|
2491
|
+
for (const node of detail.nodes) {
|
|
2492
|
+
const label = node.data?.label ?? node.id;
|
|
2493
|
+
const type = node.data?.type ?? "unknown";
|
|
2494
|
+
console.log(` ${chalk5.cyan("\u2022")} ${label} ${chalk5.gray(`(${type})`)}`);
|
|
2495
|
+
}
|
|
2496
|
+
}
|
|
2497
|
+
if (detail.parameters && Object.keys(detail.parameters).length > 0) {
|
|
2498
|
+
console.log();
|
|
2499
|
+
console.log(chalk5.bold(" \uD30C\uB77C\uBBF8\uD130:"));
|
|
2500
|
+
for (const [key, val] of Object.entries(detail.parameters)) {
|
|
2501
|
+
console.log(` ${chalk5.gray(key)}: ${JSON.stringify(val)}`);
|
|
2502
|
+
}
|
|
2503
|
+
}
|
|
2504
|
+
console.log();
|
|
2505
|
+
} catch (err) {
|
|
2506
|
+
const msg = err.message;
|
|
2507
|
+
printError(`\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uC870\uD68C \uC2E4\uD328: ${msg}`);
|
|
2508
|
+
process.exit(1);
|
|
2610
2509
|
}
|
|
2611
|
-
|
|
2612
|
-
|
|
2510
|
+
}
|
|
2511
|
+
|
|
2512
|
+
// src/commands/workflow/run.ts
|
|
2513
|
+
init_store();
|
|
2514
|
+
init_workflow();
|
|
2515
|
+
import chalk7 from "chalk";
|
|
2516
|
+
import { randomUUID } from "crypto";
|
|
2517
|
+
|
|
2518
|
+
// src/utils/sse.ts
|
|
2519
|
+
async function parseSSEStream(stream, onEvent, onDone, onError) {
|
|
2520
|
+
let buffer = "";
|
|
2521
|
+
return new Promise((resolve, reject) => {
|
|
2522
|
+
stream.on("data", (chunk) => {
|
|
2523
|
+
buffer += chunk.toString();
|
|
2524
|
+
const parts = buffer.split("\n\n");
|
|
2525
|
+
buffer = parts.pop() ?? "";
|
|
2526
|
+
for (const part of parts) {
|
|
2527
|
+
const lines = part.split("\n");
|
|
2528
|
+
let data = "";
|
|
2529
|
+
for (const line of lines) {
|
|
2530
|
+
if (line.startsWith("data: ")) {
|
|
2531
|
+
data += line.slice(6);
|
|
2532
|
+
} else if (line.startsWith("data:")) {
|
|
2533
|
+
data += line.slice(5);
|
|
2534
|
+
}
|
|
2535
|
+
}
|
|
2536
|
+
if (!data) continue;
|
|
2537
|
+
try {
|
|
2538
|
+
const event = JSON.parse(data);
|
|
2539
|
+
onEvent(event);
|
|
2540
|
+
} catch {
|
|
2541
|
+
onEvent({ type: "token", content: data });
|
|
2542
|
+
}
|
|
2543
|
+
}
|
|
2544
|
+
});
|
|
2545
|
+
stream.on("end", () => {
|
|
2546
|
+
if (buffer.trim()) {
|
|
2547
|
+
const lines = buffer.split("\n");
|
|
2548
|
+
for (const line of lines) {
|
|
2549
|
+
if (line.startsWith("data: ")) {
|
|
2550
|
+
try {
|
|
2551
|
+
const event = JSON.parse(line.slice(6));
|
|
2552
|
+
onEvent(event);
|
|
2553
|
+
} catch {
|
|
2554
|
+
onEvent({ type: "token", content: line.slice(6) });
|
|
2555
|
+
}
|
|
2556
|
+
}
|
|
2557
|
+
}
|
|
2558
|
+
}
|
|
2559
|
+
onDone?.();
|
|
2560
|
+
resolve();
|
|
2561
|
+
});
|
|
2562
|
+
stream.on("error", (err) => {
|
|
2563
|
+
onError?.(err);
|
|
2564
|
+
reject(err);
|
|
2565
|
+
});
|
|
2566
|
+
});
|
|
2567
|
+
}
|
|
2568
|
+
|
|
2569
|
+
// src/commands/workflow/run.ts
|
|
2570
|
+
init_format();
|
|
2571
|
+
|
|
2572
|
+
// src/utils/markdown.ts
|
|
2573
|
+
import chalk6 from "chalk";
|
|
2574
|
+
var CODE_BLOCK_RE = /```(\w*)\n([\s\S]*?)```/g;
|
|
2575
|
+
var INLINE_CODE_RE = /`([^`]+)`/g;
|
|
2576
|
+
var BOLD_RE = /\*\*(.+?)\*\*/g;
|
|
2577
|
+
var HEADING_RE = /^(#{1,3})\s+(.+)$/gm;
|
|
2578
|
+
var LIST_RE = /^(\s*)[-*]\s+(.+)$/gm;
|
|
2579
|
+
var LINK_RE = /\[([^\]]+)\]\(([^)]+)\)/g;
|
|
2580
|
+
function renderMarkdown(text) {
|
|
2581
|
+
let result = text;
|
|
2582
|
+
result = result.replace(CODE_BLOCK_RE, (_match, lang, code) => {
|
|
2583
|
+
const trimmed = code.trimEnd();
|
|
2584
|
+
const header = lang ? chalk6.gray(` \u2500\u2500 ${lang} \u2500\u2500`) : chalk6.gray(" \u2500\u2500 code \u2500\u2500");
|
|
2585
|
+
const lines = trimmed.split("\n").map((l) => chalk6.white(` ${l}`)).join("\n");
|
|
2586
|
+
return `
|
|
2587
|
+
${header}
|
|
2588
|
+
${lines}
|
|
2589
|
+
${chalk6.gray(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500")}
|
|
2590
|
+
`;
|
|
2591
|
+
});
|
|
2592
|
+
result = result.replace(INLINE_CODE_RE, (_m, code) => chalk6.cyan(`\`${code}\``));
|
|
2593
|
+
result = result.replace(BOLD_RE, (_m, text2) => chalk6.bold(text2));
|
|
2594
|
+
result = result.replace(HEADING_RE, (_m, hashes, text2) => {
|
|
2595
|
+
if (hashes.length === 1) return chalk6.bold.underline(text2);
|
|
2596
|
+
if (hashes.length === 2) return chalk6.bold(text2);
|
|
2597
|
+
return chalk6.bold.dim(text2);
|
|
2598
|
+
});
|
|
2599
|
+
result = result.replace(LIST_RE, (_m, indent, text2) => `${indent}${chalk6.cyan("\u2022")} ${text2}`);
|
|
2600
|
+
result = result.replace(LINK_RE, (_m, label, url) => `${chalk6.blue.underline(label)} ${chalk6.gray(`(${url})`)}`);
|
|
2601
|
+
return result;
|
|
2602
|
+
}
|
|
2603
|
+
|
|
2604
|
+
// src/commands/workflow/run.ts
|
|
2605
|
+
async function workflowRun(workflowId, input, opts) {
|
|
2606
|
+
const auth = requireAuth();
|
|
2607
|
+
let workflowName = workflowId;
|
|
2608
|
+
try {
|
|
2609
|
+
const detail = await getWorkflowDetail(workflowId);
|
|
2610
|
+
workflowName = detail.workflow_name ?? workflowId;
|
|
2611
|
+
} catch {
|
|
2612
|
+
}
|
|
2613
|
+
if (!input) {
|
|
2614
|
+
if (opts.interactive || !process.stdin.isTTY) {
|
|
2615
|
+
const { createInterface: createInterface8 } = await import("readline");
|
|
2616
|
+
const rl = createInterface8({ input: process.stdin, output: process.stdout });
|
|
2617
|
+
input = await new Promise((resolve) => {
|
|
2618
|
+
rl.question(chalk7.cyan("\uC785\uB825> "), (answer) => {
|
|
2619
|
+
rl.close();
|
|
2620
|
+
resolve(answer.trim());
|
|
2621
|
+
});
|
|
2622
|
+
});
|
|
2623
|
+
} else {
|
|
2624
|
+
printError("\uC785\uB825\uAC12\uC774 \uD544\uC694\uD569\uB2C8\uB2E4. \uC0AC\uC6A9\uBC95:");
|
|
2625
|
+
console.log(' xgen workflow run <id> "\uC785\uB825 \uD14D\uC2A4\uFFFD\uFFFD\uFFFD"');
|
|
2626
|
+
console.log(" xgen workflow run -i <id>");
|
|
2627
|
+
process.exit(1);
|
|
2628
|
+
}
|
|
2629
|
+
}
|
|
2630
|
+
if (!input) {
|
|
2631
|
+
printError("\uC785\uB825\uAC12\uC774 \uBE44\uC5B4\uC788\uC2B5\uB2C8\uB2E4");
|
|
2632
|
+
process.exit(1);
|
|
2633
|
+
}
|
|
2634
|
+
const interactionId = `cli_${randomUUID().slice(0, 8)}`;
|
|
2635
|
+
printHeader(`\uC2E4\uD589: ${workflowName}`);
|
|
2636
|
+
printInfo(`\uC785\uB825: ${input}`);
|
|
2637
|
+
console.log();
|
|
2638
|
+
try {
|
|
2639
|
+
const stream = await executeWorkflowStream({
|
|
2640
|
+
workflow_id: workflowId,
|
|
2641
|
+
workflow_name: workflowName,
|
|
2642
|
+
input_data: input,
|
|
2643
|
+
interaction_id: interactionId
|
|
2644
|
+
});
|
|
2645
|
+
let hasOutput = false;
|
|
2646
|
+
let fullResponse = "";
|
|
2647
|
+
await parseSSEStream(
|
|
2648
|
+
stream,
|
|
2649
|
+
(event) => {
|
|
2650
|
+
switch (event.type) {
|
|
2651
|
+
case "token":
|
|
2652
|
+
if (event.content) {
|
|
2653
|
+
if (!hasOutput) {
|
|
2654
|
+
hasOutput = true;
|
|
2655
|
+
console.log();
|
|
2656
|
+
}
|
|
2657
|
+
process.stdout.write(event.content);
|
|
2658
|
+
fullResponse += event.content;
|
|
2659
|
+
}
|
|
2660
|
+
break;
|
|
2661
|
+
case "log":
|
|
2662
|
+
if (opts.logs && event.content) {
|
|
2663
|
+
process.stderr.write(chalk7.gray(`[LOG] ${event.content}
|
|
2613
2664
|
`));
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2665
|
+
}
|
|
2666
|
+
break;
|
|
2667
|
+
case "node_status":
|
|
2668
|
+
if (opts.logs) {
|
|
2669
|
+
const nodeName = event.node_name ?? event.node_id ?? "?";
|
|
2670
|
+
const status = event.status ?? "?";
|
|
2671
|
+
process.stderr.write(
|
|
2672
|
+
chalk7.gray(`[\uB178\uB4DC] ${nodeName}: ${status}
|
|
2673
|
+
`)
|
|
2674
|
+
);
|
|
2675
|
+
}
|
|
2676
|
+
break;
|
|
2677
|
+
case "tool":
|
|
2678
|
+
if (opts.logs) {
|
|
2679
|
+
process.stderr.write(chalk7.gray(`[\uB3C4\uAD6C] ${JSON.stringify(event.data)}
|
|
2680
|
+
`));
|
|
2681
|
+
}
|
|
2682
|
+
break;
|
|
2683
|
+
case "complete":
|
|
2684
|
+
break;
|
|
2685
|
+
case "error":
|
|
2686
|
+
console.log();
|
|
2687
|
+
printError(event.error ?? event.content ?? "\uC54C \uC218 \uC5C6\uB294 \uC624\uB958");
|
|
2688
|
+
break;
|
|
2689
|
+
default:
|
|
2690
|
+
if (event.content) {
|
|
2691
|
+
if (!hasOutput) {
|
|
2692
|
+
process.stdout.write(chalk7.green("\uC751\uB2F5: "));
|
|
2693
|
+
hasOutput = true;
|
|
2694
|
+
}
|
|
2695
|
+
process.stdout.write(event.content);
|
|
2696
|
+
}
|
|
2697
|
+
}
|
|
2698
|
+
},
|
|
2699
|
+
() => {
|
|
2700
|
+
if (hasOutput) {
|
|
2701
|
+
console.log();
|
|
2702
|
+
if (fullResponse.includes("```") || fullResponse.includes("**")) {
|
|
2703
|
+
console.log(chalk7.gray("\u2500".repeat(40)));
|
|
2704
|
+
console.log(renderMarkdown(fullResponse));
|
|
2705
|
+
}
|
|
2706
|
+
}
|
|
2707
|
+
console.log();
|
|
2708
|
+
console.log(chalk7.gray(`\uC138\uC158: ${interactionId}`));
|
|
2709
|
+
},
|
|
2710
|
+
(err) => {
|
|
2711
|
+
console.log();
|
|
2712
|
+
printError(`\uC2A4\uD2B8\uB9AC\uBC0D \uC624\uB958: ${err.message}`);
|
|
2713
|
+
}
|
|
2714
|
+
);
|
|
2715
|
+
} catch (err) {
|
|
2716
|
+
const msg = err?.response?.data?.detail ?? err.message;
|
|
2717
|
+
printError(`\uC2E4\uD589 \uC2E4\uD328: ${msg}`);
|
|
2718
|
+
process.exit(1);
|
|
2719
|
+
}
|
|
2720
|
+
}
|
|
2721
|
+
|
|
2722
|
+
// src/commands/workflow/history.ts
|
|
2723
|
+
init_store();
|
|
2724
|
+
init_workflow();
|
|
2725
|
+
init_format();
|
|
2726
|
+
import chalk8 from "chalk";
|
|
2727
|
+
async function workflowHistory(workflowId, opts = {}) {
|
|
2728
|
+
requireAuth();
|
|
2729
|
+
const limit = opts.limit ?? 20;
|
|
2730
|
+
try {
|
|
2731
|
+
const logs = await getIOLogs(workflowId, limit);
|
|
2732
|
+
if (!logs || logs.length === 0) {
|
|
2733
|
+
console.log(chalk8.yellow("\n\uC2E4\uD589 \uC774\uB825\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.\n"));
|
|
2734
|
+
return;
|
|
2735
|
+
}
|
|
2736
|
+
printHeader(`\uC2E4\uD589 \uC774\uB825 (\uCD5C\uADFC ${logs.length}\uAC74)`);
|
|
2737
|
+
console.log();
|
|
2738
|
+
for (const log of logs) {
|
|
2739
|
+
console.log(
|
|
2740
|
+
` ${chalk8.gray(formatDate(log.created_at))} ${chalk8.cyan(log.interaction_id)}`
|
|
2741
|
+
);
|
|
2742
|
+
console.log(` ${chalk8.white("\uC785\uB825:")} ${truncate(log.input_data, 60)}`);
|
|
2743
|
+
console.log(
|
|
2744
|
+
` ${chalk8.green("\uCD9C\uB825:")} ${truncate(log.output_data, 60)}`
|
|
2745
|
+
);
|
|
2746
|
+
if (log.execution_time) {
|
|
2747
|
+
console.log(
|
|
2748
|
+
` ${chalk8.gray("\uC2DC\uAC04:")} ${(log.execution_time / 1e3).toFixed(1)}s`
|
|
2749
|
+
);
|
|
2750
|
+
}
|
|
2751
|
+
console.log();
|
|
2752
|
+
}
|
|
2753
|
+
} catch (err) {
|
|
2754
|
+
const msg = err.message;
|
|
2755
|
+
printError(`\uC774\uB825 \uC870\uD68C \uC2E4\uD328: ${msg}`);
|
|
2756
|
+
process.exit(1);
|
|
2757
|
+
}
|
|
2758
|
+
}
|
|
2759
|
+
|
|
2760
|
+
// src/commands/workflow/index.ts
|
|
2761
|
+
function registerWorkflowCommand(program2) {
|
|
2762
|
+
const wf = program2.command("workflow").alias("wf").description("\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uAD00\uB9AC \uBC0F \uC2E4\uD589");
|
|
2763
|
+
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));
|
|
2764
|
+
wf.command("info <workflow-id>").description("\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uC0C1\uC138 \uC815\uBCF4").action((id) => workflowInfo(id));
|
|
2765
|
+
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));
|
|
2766
|
+
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) }));
|
|
2767
|
+
}
|
|
2768
|
+
|
|
2769
|
+
// src/commands/chat.ts
|
|
2770
|
+
init_store();
|
|
2771
|
+
init_workflow();
|
|
2772
|
+
import chalk9 from "chalk";
|
|
2773
|
+
import { createInterface as createInterface2 } from "readline";
|
|
2774
|
+
import { randomUUID as randomUUID2 } from "crypto";
|
|
2775
|
+
init_format();
|
|
2776
|
+
var CHAT_BANNER = `
|
|
2777
|
+
${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")}
|
|
2778
|
+
${chalk9.cyan("\u2502")} ${chalk9.white.bold("XGEN")} ${chalk9.gray("\u2014 \uC6CC\uD06C\uD50C\uB85C\uC6B0 AI \uD130\uBBF8\uB110")} ${chalk9.cyan("\u2502")}
|
|
2779
|
+
${chalk9.cyan("\u2502")} ${chalk9.gray("/help \uB3C4\uC6C0\uB9D0 /workflows \uC804\uD658 /exit")} ${chalk9.cyan("\u2502")}
|
|
2780
|
+
${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")}`;
|
|
2781
|
+
function printHelp() {
|
|
2782
|
+
console.log(`
|
|
2783
|
+
${chalk9.bold("\uC2AC\uB798\uC2DC \uCEE4\uB9E8\uB4DC")}
|
|
2784
|
+
${chalk9.cyan("/workflows")} \uC6CC\uD06C\uD50C\uB85C\uC6B0 \uBAA9\uB85D \uBCF4\uAE30 & \uC804\uD658
|
|
2785
|
+
${chalk9.cyan("/switch")} \uC6CC\uD06C\uD50C\uB85C\uC6B0 \uBC88\uD638\uB85C \uC804\uD658 (\uC608: /switch 3)
|
|
2786
|
+
${chalk9.cyan("/history")} \uD604\uC7AC \uC138\uC158 \uB300\uD654 \uC774\uB825
|
|
2787
|
+
${chalk9.cyan("/clear")} \uD654\uBA74 \uC9C0\uC6B0\uAE30
|
|
2788
|
+
${chalk9.cyan("/info")} \uD604\uC7AC \uC5F0\uACB0 \uC815\uBCF4
|
|
2789
|
+
${chalk9.cyan("/help")} \uC774 \uB3C4\uC6C0\uB9D0
|
|
2790
|
+
${chalk9.cyan("/exit")} \uC885\uB8CC (Ctrl+C\uB3C4 \uAC00\uB2A5)
|
|
2791
|
+
`);
|
|
2792
|
+
}
|
|
2793
|
+
async function promptLine(rl, promptStr) {
|
|
2794
|
+
return new Promise((resolve) => {
|
|
2795
|
+
rl.question(promptStr, (answer) => resolve(answer));
|
|
2796
|
+
});
|
|
2797
|
+
}
|
|
2798
|
+
async function chat(workflowId) {
|
|
2799
|
+
const auth = requireAuth();
|
|
2800
|
+
const server = getServer();
|
|
2801
|
+
let workflows = [];
|
|
2617
2802
|
try {
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2803
|
+
workflows = await listWorkflows();
|
|
2804
|
+
} catch {
|
|
2805
|
+
printError("\uC6CC\uD06C\uD50C\uB85C\uC6B0 \uBAA9\uB85D\uC744 \uBD88\uB7EC\uC62C \uC218 \uC5C6\uC2B5\uB2C8\uB2E4");
|
|
2806
|
+
process.exit(1);
|
|
2807
|
+
}
|
|
2808
|
+
if (workflows.length === 0) {
|
|
2809
|
+
printError("\uC0AC\uC6A9 \uAC00\uB2A5\uD55C \uC6CC\uD06C\uD50C\uB85C\uC6B0\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4");
|
|
2810
|
+
process.exit(1);
|
|
2811
|
+
}
|
|
2812
|
+
let current;
|
|
2813
|
+
if (workflowId) {
|
|
2814
|
+
const found = workflows.find((w) => w.id === workflowId || w.workflow_name === workflowId);
|
|
2815
|
+
current = found ?? { id: workflowId, workflow_name: workflowId };
|
|
2816
|
+
} else {
|
|
2817
|
+
console.log(CHAT_BANNER);
|
|
2818
|
+
console.log(chalk9.gray(` \uC11C\uBC84: ${server} | \uC0AC\uC6A9\uC790: ${auth.username}
|
|
2623
2819
|
`));
|
|
2820
|
+
console.log(chalk9.bold(" \uC6CC\uD06C\uD50C\uB85C\uC6B0 \uC120\uD0DD:\n"));
|
|
2821
|
+
workflows.forEach((w, i) => {
|
|
2822
|
+
console.log(` ${chalk9.cyan(String(i + 1).padStart(3))} ${w.workflow_name}`);
|
|
2823
|
+
});
|
|
2824
|
+
console.log();
|
|
2825
|
+
const rl2 = createInterface2({ input: process.stdin, output: process.stdout });
|
|
2826
|
+
const answer = await promptLine(rl2, chalk9.cyan(" \uBC88\uD638> "));
|
|
2827
|
+
rl2.close();
|
|
2828
|
+
const idx = parseInt(answer.trim()) - 1;
|
|
2829
|
+
if (isNaN(idx) || idx < 0 || idx >= workflows.length) {
|
|
2830
|
+
current = workflows[0];
|
|
2624
2831
|
} else {
|
|
2625
|
-
|
|
2626
|
-
`));
|
|
2832
|
+
current = workflows[idx];
|
|
2627
2833
|
}
|
|
2628
|
-
} catch (err) {
|
|
2629
|
-
console.log(chalk12.red(` \u2717 ${err.message}
|
|
2630
|
-
`));
|
|
2631
|
-
}
|
|
2632
|
-
}
|
|
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
2834
|
}
|
|
2640
|
-
const
|
|
2835
|
+
const sessionId = randomUUID2().slice(0, 8);
|
|
2836
|
+
let turnCount = 0;
|
|
2837
|
+
const history = [];
|
|
2641
2838
|
console.log();
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2839
|
+
console.log(chalk9.cyan("\u2500".repeat(42)));
|
|
2840
|
+
console.log(chalk9.white.bold(` ${current.workflow_name}`));
|
|
2841
|
+
console.log(chalk9.cyan("\u2500".repeat(42)));
|
|
2842
|
+
console.log(chalk9.gray(" \uBA54\uC2DC\uC9C0\uB97C \uC785\uB825\uD558\uC138\uC694. /help \uB85C \uB3C4\uC6C0\uB9D0.\n"));
|
|
2843
|
+
const rl = createInterface2({
|
|
2844
|
+
input: process.stdin,
|
|
2845
|
+
output: process.stdout
|
|
2645
2846
|
});
|
|
2646
|
-
|
|
2647
|
-
const
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2847
|
+
const getPrompt = () => chalk9.cyan("\u276F ");
|
|
2848
|
+
const processInput = async (line) => {
|
|
2849
|
+
const input = line.trim();
|
|
2850
|
+
if (!input) return;
|
|
2851
|
+
if (input.startsWith("/")) {
|
|
2852
|
+
const [cmd, ...args] = input.slice(1).split(" ");
|
|
2853
|
+
switch (cmd.toLowerCase()) {
|
|
2854
|
+
case "exit":
|
|
2855
|
+
case "quit":
|
|
2856
|
+
case "q":
|
|
2857
|
+
console.log(chalk9.gray("\n \uC885\uB8CC\uD569\uB2C8\uB2E4.\n"));
|
|
2858
|
+
rl.close();
|
|
2859
|
+
process.exit(0);
|
|
2860
|
+
break;
|
|
2861
|
+
case "help":
|
|
2862
|
+
case "h":
|
|
2863
|
+
printHelp();
|
|
2864
|
+
break;
|
|
2865
|
+
case "clear":
|
|
2866
|
+
case "cls":
|
|
2867
|
+
console.clear();
|
|
2868
|
+
console.log(chalk9.white.bold(` ${current.workflow_name}`));
|
|
2869
|
+
console.log(chalk9.cyan("\u2500".repeat(42)));
|
|
2870
|
+
break;
|
|
2871
|
+
case "workflows":
|
|
2872
|
+
case "wf":
|
|
2873
|
+
console.log();
|
|
2874
|
+
workflows.forEach((w, i) => {
|
|
2875
|
+
const marker = w.id === current.id ? chalk9.green("\u25B8") : " ";
|
|
2876
|
+
console.log(` ${marker} ${chalk9.cyan(String(i + 1).padStart(2))} ${w.workflow_name}`);
|
|
2877
|
+
});
|
|
2878
|
+
console.log(chalk9.gray("\n /switch <\uBC88\uD638> \uB85C \uC804\uD658\n"));
|
|
2879
|
+
break;
|
|
2880
|
+
case "switch":
|
|
2881
|
+
case "sw": {
|
|
2882
|
+
const num = parseInt(args[0]);
|
|
2883
|
+
if (isNaN(num) || num < 1 || num > workflows.length) {
|
|
2884
|
+
console.log(chalk9.yellow(` 1~${workflows.length} \uC0AC\uC774 \uBC88\uD638\uB97C \uC785\uB825\uD558\uC138\uC694`));
|
|
2885
|
+
} else {
|
|
2886
|
+
current = workflows[num - 1];
|
|
2887
|
+
turnCount = 0;
|
|
2888
|
+
history.length = 0;
|
|
2889
|
+
console.log(chalk9.green(`
|
|
2890
|
+
\uC804\uD658: ${current.workflow_name}
|
|
2651
2891
|
`));
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2892
|
+
}
|
|
2893
|
+
break;
|
|
2894
|
+
}
|
|
2895
|
+
case "history":
|
|
2896
|
+
case "hist":
|
|
2897
|
+
if (history.length === 0) {
|
|
2898
|
+
console.log(chalk9.gray(" \uB300\uD654 \uC774\uB825\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.\n"));
|
|
2899
|
+
} else {
|
|
2900
|
+
console.log();
|
|
2901
|
+
for (const h of history) {
|
|
2902
|
+
const label = h.role === "user" ? chalk9.cyan("\uB098") : chalk9.green("AI");
|
|
2903
|
+
const text = h.content.length > 80 ? h.content.slice(0, 80) + "..." : h.content;
|
|
2904
|
+
console.log(` ${label}: ${text}`);
|
|
2905
|
+
}
|
|
2906
|
+
console.log();
|
|
2907
|
+
}
|
|
2908
|
+
break;
|
|
2909
|
+
case "info":
|
|
2910
|
+
console.log(`
|
|
2911
|
+
${chalk9.gray("\uC11C\uBC84:")} ${server}
|
|
2912
|
+
${chalk9.gray("\uC0AC\uC6A9\uC790:")} ${auth.username}
|
|
2913
|
+
${chalk9.gray("\uC6CC\uD06C\uD50C\uB85C\uC6B0:")} ${current.workflow_name}
|
|
2914
|
+
${chalk9.gray("\uC138\uC158:")} ${sessionId}
|
|
2915
|
+
${chalk9.gray("\uD134:")} ${turnCount}
|
|
2916
|
+
`);
|
|
2917
|
+
break;
|
|
2918
|
+
default:
|
|
2919
|
+
console.log(chalk9.yellow(` \uC54C \uC218 \uC5C6\uB294 \uCEE4\uB9E8\uB4DC: /${cmd}. /help \uCC38\uACE0`));
|
|
2920
|
+
}
|
|
2921
|
+
rl.prompt();
|
|
2922
|
+
return;
|
|
2923
|
+
}
|
|
2924
|
+
turnCount++;
|
|
2925
|
+
const interactionId = `${sessionId}_t${turnCount}`;
|
|
2926
|
+
history.push({ role: "user", content: input });
|
|
2927
|
+
process.stdout.write(chalk9.gray(" thinking..."));
|
|
2928
|
+
try {
|
|
2929
|
+
const stream = await executeWorkflowStream({
|
|
2930
|
+
workflow_id: current.id,
|
|
2931
|
+
workflow_name: current.workflow_name,
|
|
2932
|
+
input_data: input,
|
|
2933
|
+
interaction_id: interactionId
|
|
2934
|
+
});
|
|
2935
|
+
process.stdout.write("\r" + " ".repeat(20) + "\r");
|
|
2936
|
+
let fullResponse = "";
|
|
2937
|
+
let hasOutput = false;
|
|
2938
|
+
await parseSSEStream(
|
|
2939
|
+
stream,
|
|
2940
|
+
(event) => {
|
|
2941
|
+
if ((event.type === "token" || !event.type) && event.content) {
|
|
2942
|
+
if (!hasOutput) {
|
|
2943
|
+
hasOutput = true;
|
|
2944
|
+
console.log();
|
|
2945
|
+
}
|
|
2946
|
+
process.stdout.write(event.content);
|
|
2947
|
+
fullResponse += event.content;
|
|
2948
|
+
} else if (event.type === "error") {
|
|
2949
|
+
process.stdout.write("\r" + " ".repeat(20) + "\r");
|
|
2950
|
+
printError(event.error ?? event.content ?? "\uC624\uB958");
|
|
2951
|
+
}
|
|
2952
|
+
},
|
|
2953
|
+
() => {
|
|
2954
|
+
if (hasOutput) {
|
|
2955
|
+
console.log();
|
|
2956
|
+
console.log();
|
|
2957
|
+
}
|
|
2958
|
+
if (fullResponse) {
|
|
2959
|
+
history.push({ role: "assistant", content: fullResponse });
|
|
2960
|
+
}
|
|
2961
|
+
},
|
|
2962
|
+
(err) => {
|
|
2963
|
+
process.stdout.write("\r" + " ".repeat(20) + "\r");
|
|
2964
|
+
printError(`\uC2A4\uD2B8\uB9AC\uBC0D \uC624\uB958: ${err.message}`);
|
|
2965
|
+
}
|
|
2966
|
+
);
|
|
2967
|
+
} catch (err) {
|
|
2968
|
+
process.stdout.write("\r" + " ".repeat(20) + "\r");
|
|
2969
|
+
const msg = err?.response?.data?.detail ?? err.message;
|
|
2970
|
+
printError(`\uC2E4\uD589 \uC2E4\uD328: ${msg}`);
|
|
2971
|
+
}
|
|
2972
|
+
rl.prompt();
|
|
2973
|
+
};
|
|
2974
|
+
rl.setPrompt(getPrompt());
|
|
2975
|
+
rl.prompt();
|
|
2976
|
+
rl.on("line", (line) => {
|
|
2977
|
+
processInput(line).then(() => {
|
|
2978
|
+
});
|
|
2979
|
+
});
|
|
2980
|
+
rl.on("close", () => {
|
|
2981
|
+
console.log(chalk9.gray("\n \uC885\uB8CC\uD569\uB2C8\uB2E4.\n"));
|
|
2982
|
+
process.exit(0);
|
|
2983
|
+
});
|
|
2984
|
+
process.on("SIGINT", () => {
|
|
2985
|
+
console.log(chalk9.gray("\n \uC885\uB8CC\uD569\uB2C8\uB2E4.\n"));
|
|
2986
|
+
process.exit(0);
|
|
2657
2987
|
});
|
|
2658
2988
|
}
|
|
2989
|
+
function registerChatCommand(program2) {
|
|
2990
|
+
program2.command("chat [workflow-id]").description("\uC778\uD130\uB799\uD2F0\uBE0C \uB300\uD654 \uBAA8\uB4DC").action((workflowId) => chat(workflowId));
|
|
2991
|
+
}
|
|
2992
|
+
|
|
2993
|
+
// src/index.ts
|
|
2994
|
+
init_provider();
|
|
2995
|
+
init_agent();
|
|
2659
2996
|
|
|
2660
2997
|
// src/commands/doc.ts
|
|
2661
2998
|
init_store();
|
|
@@ -2715,10 +3052,38 @@ function registerDocCommand(program2) {
|
|
|
2715
3052
|
|
|
2716
3053
|
// src/commands/ontology.ts
|
|
2717
3054
|
init_store();
|
|
2718
|
-
init_ontology();
|
|
2719
|
-
init_format();
|
|
2720
3055
|
import chalk14 from "chalk";
|
|
2721
3056
|
import { createInterface as createInterface6 } from "readline";
|
|
3057
|
+
|
|
3058
|
+
// src/api/ontology.ts
|
|
3059
|
+
init_client();
|
|
3060
|
+
async function queryGraphRAG(query, graphId, opts) {
|
|
3061
|
+
const client2 = getClient();
|
|
3062
|
+
const res = await client2.post("/api/graph-rag", {
|
|
3063
|
+
query,
|
|
3064
|
+
graph_id: graphId,
|
|
3065
|
+
use_scs: opts?.scs ?? true
|
|
3066
|
+
});
|
|
3067
|
+
return res.data;
|
|
3068
|
+
}
|
|
3069
|
+
async function queryGraphRAGMultiTurn(query, sessionId, graphId, opts) {
|
|
3070
|
+
const client2 = getClient();
|
|
3071
|
+
const res = await client2.post("/api/graph-rag/multi-turn", {
|
|
3072
|
+
query,
|
|
3073
|
+
session_id: sessionId,
|
|
3074
|
+
graph_id: graphId,
|
|
3075
|
+
max_turns: opts?.maxTurns ?? 5
|
|
3076
|
+
});
|
|
3077
|
+
return res.data;
|
|
3078
|
+
}
|
|
3079
|
+
async function getGraphStats(graphId) {
|
|
3080
|
+
const client2 = getClient();
|
|
3081
|
+
const res = await client2.get(`/api/graph/${graphId}/stats`);
|
|
3082
|
+
return res.data;
|
|
3083
|
+
}
|
|
3084
|
+
|
|
3085
|
+
// src/commands/ontology.ts
|
|
3086
|
+
init_format();
|
|
2722
3087
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
2723
3088
|
function registerOntologyCommand(program2) {
|
|
2724
3089
|
const ont = program2.command("ontology").alias("ont").description("\uC628\uD1A8\uB85C\uC9C0 GraphRAG \uC9C8\uC758");
|
|
@@ -2784,42 +3149,42 @@ ${result.answer}
|
|
|
2784
3149
|
|
|
2785
3150
|
// src/index.ts
|
|
2786
3151
|
var VERSION = "0.3.0";
|
|
2787
|
-
var LOGO =
|
|
3152
|
+
var LOGO = chalk17.cyan(`
|
|
2788
3153
|
\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588 \u2588\u2588
|
|
2789
3154
|
\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588 \u2588\u2588
|
|
2790
3155
|
\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588
|
|
2791
3156
|
\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588
|
|
2792
3157
|
\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588
|
|
2793
|
-
`) +
|
|
3158
|
+
`) + chalk17.white.bold(`
|
|
2794
3159
|
\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588 \u2588\u2588
|
|
2795
3160
|
\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588 \u2588\u2588
|
|
2796
3161
|
\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588
|
|
2797
3162
|
\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588
|
|
2798
3163
|
\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588
|
|
2799
|
-
`) +
|
|
3164
|
+
`) + chalk17.gray(` v${VERSION}
|
|
2800
3165
|
`);
|
|
2801
3166
|
var BANNER = LOGO;
|
|
2802
3167
|
var program = new Command();
|
|
2803
3168
|
program.name("xgen").description("OPEN XGEN \u2014 AI Coding Agent + XGEN Platform CLI").version(VERSION).addHelpText("before", BANNER).addHelpText(
|
|
2804
3169
|
"after",
|
|
2805
3170
|
`
|
|
2806
|
-
${
|
|
2807
|
-
${
|
|
2808
|
-
${
|
|
2809
|
-
${
|
|
2810
|
-
${
|
|
3171
|
+
${chalk17.bold("\uC2DC\uC791\uD558\uAE30:")}
|
|
3172
|
+
${chalk17.cyan("xgen provider add")} AI \uD504\uB85C\uBC14\uC774\uB354 \uC124\uC815
|
|
3173
|
+
${chalk17.cyan("xgen agent")} AI \uCF54\uB529 \uC5D0\uC774\uC804\uD2B8
|
|
3174
|
+
${chalk17.cyan("xgen config set-server")} <url> XGEN \uC11C\uBC84 \uC5F0\uACB0
|
|
3175
|
+
${chalk17.cyan("xgen login")} \uC11C\uBC84 \uB85C\uADF8\uC778
|
|
2811
3176
|
|
|
2812
|
-
${
|
|
2813
|
-
${
|
|
2814
|
-
${
|
|
2815
|
-
${
|
|
3177
|
+
${chalk17.bold("AI \uC5D0\uC774\uC804\uD2B8:")}
|
|
3178
|
+
${chalk17.cyan("xgen agent")} \uCF54\uB529 \uC5D0\uC774\uC804\uD2B8 (\uD30C\uC77C, \uD130\uBBF8\uB110, \uAC80\uC0C9)
|
|
3179
|
+
${chalk17.cyan("xgen provider ls")} \uD504\uB85C\uBC14\uC774\uB354 \uBAA9\uB85D
|
|
3180
|
+
${chalk17.cyan("xgen provider add")} \uD504\uB85C\uBC14\uC774\uB354 \uCD94\uAC00
|
|
2816
3181
|
|
|
2817
|
-
${
|
|
2818
|
-
${
|
|
2819
|
-
${
|
|
2820
|
-
${
|
|
2821
|
-
${
|
|
2822
|
-
${
|
|
3182
|
+
${chalk17.bold("XGEN \uD50C\uB7AB\uD3FC:")}
|
|
3183
|
+
${chalk17.cyan("xgen chat")} \uC6CC\uD06C\uD50C\uB85C\uC6B0 \uB300\uD654
|
|
3184
|
+
${chalk17.cyan("xgen wf ls")} \uC6CC\uD06C\uD50C\uB85C\uC6B0 \uBAA9\uB85D
|
|
3185
|
+
${chalk17.cyan("xgen wf run")} <id> "\uC9C8\uBB38" \uC6CC\uD06C\uD50C\uB85C\uC6B0 \uC2E4\uD589
|
|
3186
|
+
${chalk17.cyan("xgen doc ls")} \uBB38\uC11C \uBAA9\uB85D
|
|
3187
|
+
${chalk17.cyan("xgen ont query")} "\uC9C8\uBB38" \uC628\uD1A8\uB85C\uC9C0 \uC9C8\uC758
|
|
2823
3188
|
`
|
|
2824
3189
|
);
|
|
2825
3190
|
registerConfigCommand(program);
|
|
@@ -2831,10 +3196,19 @@ registerAgentCommand(program);
|
|
|
2831
3196
|
registerDocCommand(program);
|
|
2832
3197
|
registerOntologyCommand(program);
|
|
2833
3198
|
if (process.argv.length <= 2) {
|
|
2834
|
-
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
|
|
3199
|
+
if (process.stdin.isTTY) {
|
|
3200
|
+
Promise.resolve().then(() => (init_dashboard(), dashboard_exports)).then(
|
|
3201
|
+
({ dashboard: dashboard2 }) => dashboard2().catch((err) => {
|
|
3202
|
+
console.error(chalk17.red(`\uC624\uB958: ${err.message}`));
|
|
3203
|
+
process.exit(1);
|
|
3204
|
+
})
|
|
3205
|
+
);
|
|
3206
|
+
} else {
|
|
3207
|
+
agentRepl().catch((err) => {
|
|
3208
|
+
console.error(chalk17.red(`\uC624\uB958: ${err.message}`));
|
|
3209
|
+
process.exit(1);
|
|
3210
|
+
});
|
|
3211
|
+
}
|
|
2838
3212
|
} else {
|
|
2839
3213
|
program.parse();
|
|
2840
3214
|
}
|