#include #include #include #include #ifdef _WIN32 #include #else #include #include #include #endif #include "dstalk/dstalk_api.h" // ---- ANSI 简写 ---- #define CLR_RESET "\033[0m" #define CLR_CYAN "\033[36m" #define CLR_YELLOW "\033[33m" #define CLR_GREEN "\033[32m" #define CLR_RED "\033[31m" #define CLR_DIM "\033[2m" #define CLR_BOLD "\033[1m" // ---- 工具函数 ---- static void print_banner() { std::printf("%sdstalk v0.1.0%s | %sDeepSeek V4%s | " "%s/help%s 查看帮助 | %s/quit%s 退出\n", CLR_CYAN CLR_BOLD, CLR_RESET, CLR_GREEN, CLR_RESET, CLR_DIM, CLR_RESET, CLR_DIM, CLR_RESET); } static void print_help() { std::printf("\n%s命令列表:%s\n", CLR_BOLD, CLR_RESET); std::printf(" %s/help%s 显示此帮助\n", CLR_YELLOW, CLR_RESET); std::printf(" %s/quit%s 退出程序\n", CLR_YELLOW, CLR_RESET); std::printf(" %s/clear%s 清空当前会话上下文\n", CLR_YELLOW, CLR_RESET); std::printf(" %s/model %s 切换模型\n", CLR_YELLOW, CLR_RESET); std::printf(" %s/file read %s 读取文件内容\n", CLR_YELLOW, CLR_RESET); std::printf(" %s/file write

%s写入文件\n", CLR_YELLOW, CLR_RESET); std::printf(" %s/save %s 保存会话\n", CLR_YELLOW, CLR_RESET); std::printf(" %s/load %s 恢复会话\n", CLR_YELLOW, CLR_RESET); std::printf("\n直接输入问题即可与 AI 对话。\n\n"); } static void handle_command(const char* line) { if (!line || line[0] != '/') return; // /quit if (std::strcmp(line, "/quit") == 0 || std::strcmp(line, "/q") == 0) { dstalk_destroy(); std::printf(CLR_DIM "再见!\n" CLR_RESET); std::exit(0); } // /help if (std::strcmp(line, "/help") == 0 || std::strcmp(line, "/h") == 0) { print_help(); return; } // /clear if (std::strcmp(line, "/clear") == 0) { dstalk_session_clear(); std::printf(CLR_GREEN "[OK] 会话已清空\n" CLR_RESET); return; } // /model if (std::strncmp(line, "/model ", 7) == 0) { const char* model = line + 7; while (*model == ' ') model++; dstalk_set_model(model); std::printf(CLR_GREEN "[OK] 模型已切换: %s\n" CLR_RESET, model); return; } // /file read if (std::strncmp(line, "/file read ", 11) == 0) { const char* path = line + 11; while (*path == ' ') path++; char* content = nullptr; if (dstalk_file_read(path, &content) == 0 && content) { std::printf("%s--- %s ---%s\n", CLR_DIM, path, CLR_RESET); std::printf("%s\n", content); std::printf(CLR_DIM "--- EOF ---\n" CLR_RESET); dstalk_free_string(content); } else { std::printf(CLR_RED "[ERROR] 无法读取: %s\n" CLR_RESET, path); } return; } // /file write if (std::strncmp(line, "/file write ", 12) == 0) { const char* rest = line + 12; while (*rest == ' ') rest++; // 第一个参数是路径,后面到行尾是内容 const char* space = std::strchr(rest, ' '); if (!space) { std::printf(CLR_RED "[ERROR] 用法: /file write \n" CLR_RESET); return; } std::string path(rest, space - rest); const char* content = space + 1; while (*content == ' ') content++; if (dstalk_file_write(path.c_str(), content) == 0) { std::printf(CLR_GREEN "[OK] 已写入: %s\n" CLR_RESET, path.c_str()); } else { std::printf(CLR_RED "[ERROR] 写入失败: %s\n" CLR_RESET, path.c_str()); } return; } // /save if (std::strncmp(line, "/save ", 6) == 0) { const char* path = line + 6; while (*path == ' ') path++; if (dstalk_session_save(path) == 0) { std::printf(CLR_GREEN "[OK] 会话已保存: %s\n" CLR_RESET, path); } else { std::printf(CLR_RED "[ERROR] 保存失败: %s\n" CLR_RESET, path); } return; } // /load if (std::strncmp(line, "/load ", 6) == 0) { const char* path = line + 6; while (*path == ' ') path++; if (dstalk_session_load(path) == 0) { std::printf(CLR_GREEN "[OK] 会话已恢复: %s\n" CLR_RESET, path); } else { std::printf(CLR_RED "[ERROR] 恢复失败: %s\n" CLR_RESET, path); } return; } std::printf(CLR_RED "未知命令: %s (输入 /help 查看帮助)\n" CLR_RESET, line); } // ---- 主程序 ---- int main(int argc, char* argv[]) { // Windows: 启用 ANSI 转义码支持 #ifdef _WIN32 HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); DWORD mode = 0; GetConsoleMode(hOut, &mode); SetConsoleMode(hOut, mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING); #endif // 查找配置文件 const char* config_path = nullptr; if (argc >= 2) { config_path = argv[1]; } else { // 默认路径 #ifdef _WIN32 const char* default_configs[] = {"config.toml", nullptr}; #else const char* default_configs[] = {"config.toml", nullptr}; #endif for (int i = 0; default_configs[i]; i++) { FILE* f = nullptr; #ifdef _WIN32 fopen_s(&f, default_configs[i], "r"); #else f = fopen(default_configs[i], "r"); #endif if (f) { fclose(f); config_path = default_configs[i]; break; } } } if (dstalk_init(config_path) != 0) { std::fprintf(stderr, CLR_RED "[dstalk] 初始化失败\n" CLR_RESET); return 1; } std::printf("\n"); print_banner(); std::printf("\n"); char buffer[8192]; while (true) { std::printf(CLR_YELLOW "> " CLR_RESET); std::fflush(stdout); if (!std::fgets(buffer, sizeof(buffer), stdin)) break; // 去除末尾换行 size_t len = std::strlen(buffer); while (len > 0 && (buffer[len-1] == '\n' || buffer[len-1] == '\r')) { buffer[--len] = '\0'; } if (len == 0) continue; // 命令处理 if (buffer[0] == '/') { handle_command(buffer); continue; } // AI 对话 std::printf(CLR_DIM "思考中..." CLR_RESET "\n"); std::fflush(stdout); char* reply = nullptr; int ret = dstalk_chat(buffer, &reply); if (ret == 0 && reply) { std::printf("\n%s\n\n", reply); dstalk_free_string(reply); } else { std::printf(CLR_RED "[ERROR] AI 调用失败" CLR_RESET); if (reply) { std::printf(": %s", reply); dstalk_free_string(reply); } std::printf("\n"); } } dstalk_destroy(); return 0; }