using System.Net.Http; using System.Net.Http.Headers; using System.Text; using System.Text.Json; using System.Text.Json.Serialization; namespace AiAgent.Core.Infrastructure { /// /// A client for interacting with the x.ai (Grok) API. /// public class GrokClient { private readonly HttpClient _httpClient; private const string ApiUrl = "https://api.x.ai/v1/chat/completions"; /// /// Initializes a new instance of the GrokClient. /// /// Your x.ai API key. public GrokClient(string apiKey) { _httpClient = new HttpClient(); _httpClient.Timeout = TimeSpan.FromMinutes(60); _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", apiKey); _httpClient.DefaultRequestHeaders.Add("User-Agent", "NewAI/1.0"); // Optional, but helps } public static async Task Query(string prompt) { var apiKey = "xai-AR8626vr2xOffBhsnhs3vKXGPePi9h4JDRhOshRUGYOU2lEuuyXAtGO5iiHINVUf96qODKZlaX9FSxJW"; var client = new GrokClient(apiKey); return await client.GetChatCompletionAsync(prompt); } /// /// Sends a prompt to the Grok API and gets a response. /// /// The user's question or prompt. /// The content of the AI's response, or an error message. public async Task GetChatCompletionAsync(string prompt) { var requestBody = new GrokRequest { messages = new List { new GrokMessage { role = "user", content = prompt } }, model = "grok-4-fast-reasoning", // "grok-4-0709", // stream = false, temperature = 0.0 }; //try //{ var jsonRequest = JsonSerializer.Serialize(requestBody).Replace("\\r", ""); var grokRequestLogFile = Path.Combine("Archive", "grok_request.json"); File.WriteAllText(grokRequestLogFile, jsonRequest + Environment.NewLine); var content = new StringContent(jsonRequest, Encoding.UTF8, "application/json"); try { var response = await _httpClient.PostAsync(ApiUrl, content); if (response.IsSuccessStatusCode) { var jsonResponse = await response.Content.ReadAsStringAsync(); var grokResponse = JsonSerializer.Deserialize(jsonResponse); File.WriteAllText(grokRequestLogFile, jsonResponse + Environment.NewLine); string metadataLogFile = grokRequestLogFile + ".csv"; if (!File.Exists(metadataLogFile)) File.WriteAllText(metadataLogFile, "Timestamp,Model,PromptTokens,CompletionTokens,TotalTokens,ReasoningTokens,SystemFingerprint" + Environment.NewLine); File.AppendAllText(metadataLogFile, $"{DateTime.Now}," + $"{grokResponse.Model}," + $"{grokResponse.Usage.PromptTokens}," + $"{grokResponse.Usage.CompletionTokens}," + $"{grokResponse.Usage.TotalTokens}," + $"{grokResponse.Usage.CompletionTokensDetails.ReasoningTokens}," + $"{grokResponse.SystemFingerprint}{Environment.NewLine}"); return grokResponse?.Choices?.FirstOrDefault()?.Message?.Content ?? "No content received."; } else { var errorContent = await response.Content.ReadAsStringAsync(); return $"Error: {response.StatusCode} - {errorContent}"; } // Rest of your logic } catch (HttpRequestException ex) { Console.WriteLine($"HttpRequestException: {ex.Message}"); if (ex.InnerException != null) { Console.WriteLine($"Inner Exception: {ex.InnerException.GetType().Name} - {ex.InnerException.Message}"); } throw; // Re-throw to see if it crashes your app } //} //catch (Exception ex) //{ // return $"An exception occurred: {ex.Message}"; //} } } public class GrokMessage { public string role { get; set; } public string content { get; set; } } public class GrokRequest { public List messages { get; set; } public string model { get; set; } public bool stream { get; set; } public double temperature { get; set; } } public class GrokChoice { public GrokMessage message { get; set; } } public class GrokResponse { [JsonPropertyName("id")] public string Id { get; set; } [JsonPropertyName("object")] // "object" is a C# keyword, so the attribute is required public string ObjectType { get; set; } [JsonPropertyName("created")] public long Created { get; set; } // Unix timestamp [JsonPropertyName("model")] public string Model { get; set; } [JsonPropertyName("choices")] public List Choices { get; set; } [JsonPropertyName("usage")] public Usage Usage { get; set; } [JsonPropertyName("system_fingerprint")] public string SystemFingerprint { get; set; } } public class Choice { [JsonPropertyName("index")] public int Index { get; set; } [JsonPropertyName("message")] public Message Message { get; set; } [JsonPropertyName("finish_reason")] public string FinishReason { get; set; } } public class Message { [JsonPropertyName("role")] public string Role { get; set; } [JsonPropertyName("content")] public string Content { get; set; } } public class Usage { [JsonPropertyName("prompt_tokens")] public int PromptTokens { get; set; } [JsonPropertyName("completion_tokens")] public int CompletionTokens { get; set; } [JsonPropertyName("total_tokens")] public int TotalTokens { get; set; } // Add this property [JsonPropertyName("prompt_tokens_details")] public PromptTokensDetails PromptTokensDetails { get; set; } // And add this property [JsonPropertyName("completion_tokens_details")] public CompletionTokensDetails CompletionTokensDetails { get; set; } [JsonPropertyName("num_sources_used")] public int NumSourcesUsed { get; set; } } public class PromptTokensDetails { [JsonPropertyName("text_tokens")] public int TextTokens { get; set; } [JsonPropertyName("cached_tokens")] public int CachedTokens { get; set; } } public class CompletionTokensDetails { [JsonPropertyName("reasoning_tokens")] public int ReasoningTokens { get; set; } } }