/* * LLM Proxy Client - C Version (Windows Native using WinINet) * Compile: gcc -o llm_client client.c -lwininet * Usage: llm_client.exe */ #include #include #include #include #include #define MAX_PROMPT_SIZE 4096 #define MAX_RESPONSE_SIZE 65536 typedef struct { const char *name; const char *id; } LLMModel; static const LLMModel MODELS[] = { {"Laguna S 2.1 (Free)", "poolside/laguna-s-2.1:free"}, {"Gemini 3.6 Flash (Paid)", "google/gemini-3.6-flash"}, {"Claude Opus 5 (Paid)", "anthropic/claude-opus-5"}, {"Claude Fable 5 (Paid)", "anthropic/claude-fable-5"}, {"GPT-5.6 Sol (Paid)", "openai/gpt-5.6-sol"}, {"GPT-5.6 Luna (Paid)", "openai/gpt-5.6-luna"}, {"Nemotron 3 Ultra (Free)", "nvidia/nemotron-3-ultra-550b-a55b:free"} }; static const int MODEL_COUNT = sizeof(MODELS) / sizeof(MODELS[0]); char* ask_llm(const char *prompt, const LLMModel *model) { HINTERNET hInternet = NULL, hConnect = NULL, hRequest = NULL; char *response = NULL; DWORD bytesRead = 0; DWORD totalSize = 0; char headers[512]; response = (char*)malloc(MAX_RESPONSE_SIZE); if (!response) return _strdup("Error: Memory allocation failed"); memset(response, 0, MAX_RESPONSE_SIZE); /* Initialize WinINet */ hInternet = InternetOpenA("LLM-Proxy-Client/1.0", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); if (!hInternet) { free(response); return _strdup("Error: Failed to open Internet session"); } /* Connect to server */ hConnect = InternetConnectA(hInternet, "ttl0110-llm-proxy.hf.space", INTERNET_DEFAULT_HTTPS_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0); if (!hConnect) { InternetCloseHandle(hInternet); free(response); return _strdup("Error: Failed to connect to server"); } /* Create request */ hRequest = HttpOpenRequestA(hConnect, "POST", "/ask", NULL, NULL, NULL, INTERNET_FLAG_SECURE | INTERNET_FLAG_RELOAD, 0); if (!hRequest) { InternetCloseHandle(hConnect); InternetCloseHandle(hInternet); free(response); return _strdup("Error: Failed to create request"); } /* Build headers */ snprintf(headers, sizeof(headers), "Content-Type: text/plain\r\nX-Model: %s", model->id); /* Send request */ DWORD promptLen = (DWORD)strlen(prompt); if (!HttpSendRequestA(hRequest, headers, (DWORD)strlen(headers), (LPVOID)prompt, promptLen)) { DWORD err = GetLastError(); char errMsg[128]; snprintf(errMsg, sizeof(errMsg), "Error: Failed to send request (code: %lu)", err); InternetCloseHandle(hRequest); InternetCloseHandle(hConnect); InternetCloseHandle(hInternet); free(response); return _strdup(errMsg); } /* Read response data */ char buffer[4096]; while (InternetReadFile(hRequest, buffer, sizeof(buffer) - 1, &bytesRead) && bytesRead > 0) { if (totalSize + bytesRead < MAX_RESPONSE_SIZE - 1) { memcpy(response + totalSize, buffer, bytesRead); totalSize += bytesRead; } } response[totalSize] = '\0'; /* Cleanup */ InternetCloseHandle(hRequest); InternetCloseHandle(hConnect); InternetCloseHandle(hInternet); return response; } void clear_input_buffer(void) { int c; while ((c = getchar()) != '\n' && c != EOF); } int main(void) { char prompt[MAX_PROMPT_SIZE]; char prompt_prefix[MAX_PROMPT_SIZE] = {0}; int choice = 0; /* Set console to UTF-8 */ SetConsoleOutputCP(CP_UTF8); SetConsoleCP(CP_UTF8); printf("=== C LLM Assistant (HuggingFace Proxy) ===\n\n"); /* Model Selection */ printf("Chon Model LLM:\n"); for (int i = 0; i < MODEL_COUNT; i++) { printf("%d. %s\n", i + 1, MODELS[i].name); } while (choice < 1 || choice > MODEL_COUNT) { printf("Nhap lua chon (1-%d): ", MODEL_COUNT); if (scanf("%d", &choice) != 1) { clear_input_buffer(); choice = 0; } } clear_input_buffer(); const LLMModel *selected_model = &MODELS[choice - 1]; printf("Ban da chon: %s\n\n", selected_model->name); printf("Nhap prompt prefix (bo trong neu khong dung): "); if (fgets(prompt_prefix, sizeof(prompt_prefix), stdin) != NULL) { prompt_prefix[strcspn(prompt_prefix, "\r\n")] = '\0'; } printf("Huong dan: Nhap prompt cua ban. Nhap dong trong de gui.\n"); printf("Nhap 'EXIT' de thoat.\n"); while (1) { printf("\nBan [%s]:\n", selected_model->name); char full_prompt[MAX_PROMPT_SIZE] = {0}; size_t total_len = 0; while (1) { if (fgets(prompt, sizeof(prompt), stdin) == NULL) { break; } /* Check for EXIT command */ if (_strnicmp(prompt, "EXIT", 4) == 0 && (prompt[4] == '\n' || prompt[4] == '\0')) { printf("Tam biet!\n"); return 0; } /* Empty line means submit */ if (prompt[0] == '\n') { break; } size_t line_len = strlen(prompt); if (total_len + line_len < MAX_PROMPT_SIZE - 1) { strcat(full_prompt, prompt); total_len += line_len; } } if (total_len == 0) { printf("Prompt trong, vui long nhap lai.\n"); continue; } /* Remove trailing newline */ if (full_prompt[total_len - 1] == '\n') { full_prompt[total_len - 1] = '\0'; } char request_prompt[MAX_PROMPT_SIZE] = {0}; if (prompt_prefix[0] != '\0') { int written = snprintf(request_prompt, sizeof(request_prompt), "%s\n\n%s", prompt_prefix, full_prompt); if (written < 0 || written >= (int)sizeof(request_prompt)) { printf("Prompt va prefix qua dai, vui long nhap lai.\n"); continue; } } else { strcpy(request_prompt, full_prompt); } printf("Thinking...\n"); char *response = ask_llm(request_prompt, selected_model); printf("\n[LLM]: %s\n", response); printf("-------------------------------------------\n"); free(response); } return 0; }