library(shiny) library(httr) library(jsonlite) library(commonmark) library(glue) source("llm_api.R") source("package_manager_module.R") ui <- fluidPage( titlePanel("AI-Assisted R Analysis Tool"), sidebarLayout( sidebarPanel( h4("LLM Chat"), passwordInput("api_key", "Enter your Groq API Key:", ""), div( style = 'overflow-y: auto; overflow-x: hidden; height: 300px; border: 1px solid #ccc; padding: 10px; word-wrap: break-word;', uiOutput("chat_output") ), textInput("chat_input", "Your Question or Command:", ""), actionButton("chat_submit", "Ask LLM") ), mainPanel( tabsetPanel( type = "tabs", tabPanel( "R Code Box", textAreaInput( "r_code_input", "R Script Editor:", "plot(1:10, 1:10, main = 'Example Plot')", height = "300px", width = "100%" ), actionButton("run_r_code", "Run Code") ), tabPanel( "Console Output", uiOutput("console_output") ), tabPanel( "Display Pane", plotOutput("display_plot") ), packageManagerUI("package_manager"), tabPanel( "LLM API", verbatimTextOutput("llm_api_output") ) ) ) ) ) server <- function(input, output, session) { conversation_history <- reactiveVal(list()) console_output_value <- reactiveVal(NULL) last_response <- reactiveVal(NULL) last_request <- reactiveVal(NULL) model <- "llama3-8b-8192" # Replace with your desired model packageManagerServer("package_manager") submit_chat <- function() { req(input$chat_input) api_key <- input$api_key if (is.null(api_key) || api_key == "") { showNotification("Please enter your Groq API Key.", type = "error") return(NULL) } # Create the history variable history <- conversation_history() # Append the user's message to the history user_message <- list(role = "user", content = input$chat_input) history <- append(history, list(user_message)) # Update the UI conversation_history(history) # Read and prepare the system message r_code <- input$r_code_input console_output <- paste(console_output_value(), collapse = "\n") system_message <- glue(paste(readLines("system_message.txt"), collapse = "\n")) tryCatch({ # Call send_chat_completion and get the response response_data <- send_chat_completion( api_key = api_key, system_message = system_message, model = model, messages = history ) # Now extract the assistant's message response_json <- response_data$response_json # Display the request and response in the LLM API tab last_request(response_data$request_body) # Re-serialize the response JSON with pretty formatting last_response( toJSON(response_data$response_json, auto_unbox = TRUE, pretty = TRUE) ) # Debugging statements # print("Structure of response_json:") # print(str(response_json)) # Access the assistant's message if (!is.null(response_json$choices)) { choices <- response_json$choices assistant_message <- response_json$choices[[1]]$message$content # print("Assistant's message content:") # print(assistant_message) # Append the assistant's response to the conversation history history <- append(history, list( list(role = "assistant", content = assistant_message) )) conversation_history(history) # Update the chat output output$chat_output <- renderUI({ msgs <- lapply(conversation_history(), function(msg) { # Convert the Markdown content to HTML content_html <- commonmark::markdown_html(msg$content) # Create a div for each message tags$div( tags$p(tags$b(paste0(msg$role, ":"))), # Display the role in bold HTML(content_html) # Render the converted HTML content ) }) do.call(tagList, msgs) }) # Clear the chat input field updateTextInput(session, "chat_input", value = "") } else if (!is.null(response_json$error)) { # Handle API error response showNotification(paste("API Error:", response_json$error$message), type = "error") } else { # Unexpected response structure showNotification("Unexpected response from the API.", type = "error") } }, error = function(e) { showNotification(paste("Error:", e$message), type = "error") }) } observeEvent(input$chat_submit, { submit_chat() }) # Existing code for running R code and updating the console and display pane remains unchanged observeEvent(input$run_r_code, { code <- input$r_code_input result <- tryCatch({ output_text <- capture.output(eval(parse(text = code))) output_text }, error = function(e) { e$message }) console_output_value(result) output$console_output <- renderUI({ HTML(paste(result, collapse = "
")) }) }) output$display_plot <- renderPlot({ input$run_r_code code <- isolate(input$r_code_input) tryCatch({ eval(parse(text = code)) }, error = function(e) { plot.new() text(0.5, 0.5, paste("Error:", e$message), cex = 1.5) }) }) output$llm_api_output <- renderPrint({ cat("Last Request:\n") cat(last_request(), "\n\n") cat("Last Response:\n") cat(last_response()) }) } shinyApp(ui = ui, server = server)