TutoR / package_manager_module.R
spanasch's picture
Implement semantic package search
33306b8
Raw History Blame Contribute Delete
4.65 kB
# package_manager_module.R
source("semantic_package_search2.R")
# UI function for the Package Manager module
packageManagerUI <- function(id) {
ns <- NS(id) # Namespace function to avoid ID collisions
tabPanel(
"Package Manager",
fluidPage(
# Search Panel with distinct background color
div(
style = "background-color: #f7f7f7; padding: 20px; border-radius: 5px; margin-bottom: 20px;",
fluidRow(
column(
width = 12,
div(
style = "margin-bottom: 10px;",
tags$label(
`for` = ns("task_description"),
"Description of the task you want to accomplish",
style = "font-weight: bold; margin-right: 10px; white-space: nowrap;"
),
textInput(
ns("task_description"),
label = NULL,
width = "100%",
placeholder = "Enter a description of your task..."
)
),
actionButton(ns("search_button"), "Search Packages", style = "margin-top: 10px;")
)
)
),
# Suggestions List
fluidRow(
column(
width = 12,
h3("Package Suggestions"),
uiOutput(ns("package_list"))
)
)
)
)
}
# Server function for the Package Manager module
packageManagerServer <- function(id) {
moduleServer(
id,
function(input, output, session) {
ns <- session$ns
# Function to get package suggestions using semantic search
getPackageSuggestions <- function(task_description) {
# Get results from semantic search
results <- semantic_package_search(
query = task_description,
embeddings_df = embeddings_df,
packages_df = packages_df,
top_n = 6 # Adjust number of suggestions as needed
)
# Convert results to list format expected by UI
suggestions <- lapply(1:nrow(results), function(i) {
list(
name = results$Package[i],
description = paste0(
results$Title[i],
"\n\n",
results$Description[i],
"\n\nSimilarity score: ",
round(results$similarity_score[i], 4)
)
)
})
return(suggestions)
}
# Reactive value to store package suggestions
package_suggestions <- reactiveVal(NULL)
# Observe the search button to get package suggestions
observeEvent(input$search_button, {
req(input$task_description) # Ensure input is not empty
# Get suggestions using semantic search
suggestions <- tryCatch({
getPackageSuggestions(input$task_description)
}, error = function(e) {
showNotification(
paste("Error getting suggestions:", e$message),
type = "error"
)
NULL
})
package_suggestions(suggestions)
})
output$package_list <- renderUI({
suggestions <- package_suggestions()
if (is.null(suggestions)) {
return(NULL)
}
# Generate UI elements for each package suggestion
suggestion_ui <- lapply(seq_along(suggestions), function(i) {
pkg <- suggestions[[i]]
div(
style = "border: 1px solid #ddd; padding: 10px; margin-bottom: 10px; border-radius: 5px; box-shadow: 2px 2px 5px rgba(0,0,0,0.1); display: flex; justify-content: space-between; align-items: center;",
div(
style = "flex-grow: 1;",
h4(pkg$name, style = "margin: 0;"),
p(pkg$description, style = "margin: 0; white-space: pre-wrap;") # Added pre-wrap to preserve newlines
),
div(
style = "flex-shrink: 0;",
actionButton(ns(paste0("install_", i)), "Install", style = "margin-left: 40px;")
)
)
})
do.call(tagList, suggestion_ui)
})
# Observe install buttons
observe({
suggestions <- package_suggestions()
if (is.null(suggestions)) {
return(NULL)
}
lapply(seq_along(suggestions), function(i) {
pkg <- suggestions[[i]]
install_btn <- paste0("install_", i)
observeEvent(input[[install_btn]], {
# For now, we'll just show a notification
showNotification(paste("Installing package:", pkg$name))
# Actual installation logic can be added here
})
})
})
}
)
}