| |
| library(shiny) |
| library(httr2) |
|
|
| |
| |
| nim_base_url <- Sys.getenv("OPENAI_BASE_URL", unset = "https://integrate.api.nvidia.com/v1") |
|
|
| ui <- fluidPage( |
| titlePanel("Chat com NVIDIA NIM via httr2 (Shiny)"), |
| sidebarLayout( |
| sidebarPanel( |
| textInput("model", "Modelo (NIM)", value = "meta/llama-3.1-70b-instruct"), |
| textAreaInput("system", "System prompt:", value = "You are a helpful assistant.", rows = 2), |
| textAreaInput("pergunta", "Pergunta (user):", value = "Descreva o package leaflet no R.", rows = 4), |
| sliderInput("temperature", "temperature:", min = 0, max = 1, value = 0.2, step = 0.1), |
| numericInput("max_tokens", "max_tokens:", value = 400, min = 1, step = 50), |
| actionButton("enviar", "Enviar", class = "btn-primary"), |
| tags$hr(), |
| helpText("Defina a variável de ambiente OPENAI_API_KEY nas configurações do Space.") |
| ), |
| mainPanel( |
| h4("Resposta"), |
| uiOutput("status"), |
| verbatimTextOutput("resposta"), |
| tags$hr(), |
| |
| verbatimTextOutput("payload", placeholder = TRUE) |
| ) |
| ) |
| ) |
|
|
| server <- function(input, output, session) { |
| resposta <- reactiveVal("") |
| status <- reactiveVal("") |
| payload <- reactiveVal(NULL) |
|
|
| observeEvent(input$enviar, { |
| |
| if (Sys.getenv("OPENAI_API_KEY", unset = "") == "") { |
| resposta("Erro: a variável OPENAI_API_KEY não está definida nas variáveis do Space.") |
| return(invisible(NULL)) |
| } |
|
|
| status("Enviando… aguarde") |
| resposta("") |
|
|
| body <- list( |
| model = input$model, |
| messages = list( |
| list(role = "system", content = input$system), |
| list(role = "user", content = input$pergunta) |
| ), |
| temperature = input$temperature, |
| max_tokens = input$max_tokens |
| ) |
|
|
| payload(body) |
|
|
| req <- request(paste0(nim_base_url, "/chat/completions")) |> |
| req_headers( |
| Authorization = paste("Bearer", Sys.getenv("OPENAI_API_KEY")), |
| `Content-Type` = "application/json" |
| ) |> |
| req_body_json(body) |
|
|
| tryCatch({ |
| resp <- req_perform(req) |
| if (resp_status(resp) >= 300) { |
| status(paste("HTTP", resp_status(resp))) |
| } else { |
| status("OK") |
| } |
| out <- resp_body_json(resp) |
| |
| msg <- tryCatch(out$choices[[1]]$message$content, error = function(e) NULL) |
| if (is.null(msg)) { |
| |
| msg <- tryCatch(out$choices[[1]]$text, error = function(e) "(sem conteúdo)") |
| } |
| resposta(msg) |
| }, error = function(e) { |
| status("Erro na requisição") |
| resposta(paste("Erro:", e$message)) |
| }) |
| }) |
|
|
| output$resposta <- renderText(resposta()) |
| output$status <- renderUI({ |
| s <- status() |
| if (!nzchar(s)) return(NULL) |
| div(style = "margin-bottom:8px;", strong("Status:"), span(s)) |
| }) |
| |
| } |
|
|
| shinyApp(ui, server) |
|
|
|
|