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