| Title: | AI Assistant Gadget for 'RStudio' |
|---|---|
| Description: | Provides an interactive 'RStudio' gadget for working with an AI assistant during package and script development. The gadget can use selected editor text, the active source file, package metadata, and uploaded files as context for code explanation, code generation, documentation, and review workflows. It offers model presets, assistant behavior settings, responsive code-focused output, and explicit copy, insert, and replace actions for the active source editor. API interactions via the 'httr' package are performed asynchronously using 'promises' and 'future' to avoid blocking the R console. The backend is configured via the OPENAI_API_KEY environment variable. |
| Authors: | Antoni Czolgowski [aut, cre] |
| Maintainer: | Antoni Czolgowski <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.1.3 |
| Built: | 2026-06-29 19:58:35 UTC |
| Source: | https://github.com/cran/PacketLLM |
Add attachment to active conversation
add_attachment_to_active_conversation(name, content)add_attachment_to_active_conversation(name, content)
name |
File name. |
content |
File content as string. |
Logical.
Locks the model on the first assistant message. Sets title on the first user message.
add_message_to_active_history(role, content)add_message_to_active_history(role, content)
role |
'user'|'assistant'|'system' |
content |
Message content |
Result list (type + extra fields) or error list.
Add user message to the active conversation
add_user_message(text)add_user_message(text)
text |
Single character string. |
Invisible NULL.
Returns the model presets shown in the PacketLLM UI.
available_model_presets()available_model_presets()
A data frame with preset labels, model IDs, and descriptions.
List of available AI models for selection in the UI
available_openai_modelsavailable_openai_models
Sends messages to the Responses API and returns assistant text.
call_openai_chat( messages, model, reasoning_effort = "medium", verbosity = "low", max_output_tokens = NA_integer_ )call_openai_chat( messages, model, reasoning_effort = "medium", verbosity = "low", max_output_tokens = NA_integer_ )
messages |
List of messages, each with |
model |
Model ID to use. |
reasoning_effort |
Reasoning effort: |
verbosity |
Output verbosity: |
max_output_tokens |
Optional maximum output tokens. |
Character string with assistant reply, or NULL on unexpected response.
## Not run: msgs <- list(list(role = "user", content = "What does httr do?")) call_openai_chat(messages = msgs, model = "gpt-5.4-mini") ## End(Not run)## Not run: msgs <- list(list(role = "user", content = "What does httr do?")) call_openai_chat(messages = msgs, model = "gpt-5.4-mini") ## End(Not run)
Captures lightweight context from the active RStudio editor and project. The function returns a graceful empty context outside RStudio.
capture_rstudio_context(mode = "auto", max_chars = 6000)capture_rstudio_context(mode = "auto", max_chars = 6000)
mode |
One of |
max_chars |
Maximum characters to keep from source content. |
A structured list describing the captured context.
Verifies that OPENAI_API_KEY is set. Stops if missing.
check_api_key()check_api_key()
Invisible TRUE if set.
## Not run: check_api_key() ## End(Not run)## Not run: check_api_key() ## End(Not run)
Create a new conversation
create_new_conversation( activate = FALSE, add_initial_settings = TRUE, title = NULL )create_new_conversation( activate = FALSE, add_initial_settings = TRUE, title = NULL )
activate |
Logical. Activate immediately? |
add_initial_settings |
Logical. Add default model and system message? |
title |
Optional title; if NULL, a time-based title is used. |
Character: conversation ID.
Delete a conversation
delete_conversation(id)delete_conversation(id)
id |
Conversation ID. |
TRUE if deleted, FALSE otherwise.
Get active chat history
get_active_chat_history()get_active_chat_history()
List of messages (possibly empty).
Get active conversation object
get_active_conversation()get_active_conversation()
List or NULL.
Get attachments for active conversation
get_active_conversation_attachments()get_active_conversation_attachments()
List (possibly empty).
Get active conversation ID
get_active_conversation_id()get_active_conversation_id()
Character or NULL.
Get all conversation IDs
get_all_conversation_ids()get_all_conversation_ids()
Character vector.
Prepares messages and calls the API. Adds the reply to history.
get_assistant_response()get_assistant_response()
Character with assistant reply or error message.
Get attachments by ID
get_conversation_attachments(id)get_conversation_attachments(id)
id |
Conversation ID. |
List or NULL.
Get conversation data by ID
get_conversation_data(id)get_conversation_data(id)
id |
Conversation ID. |
List or NULL.
Get conversation history by ID
get_conversation_history(id)get_conversation_history(id)
id |
Conversation ID. |
List or NULL.
Get model for conversation
get_conversation_model(id)get_conversation_model(id)
id |
Conversation ID. |
Character or NULL.
Get conversation title by ID
get_conversation_title(id)get_conversation_title(id)
id |
Conversation ID. |
Character or NULL.
Initializes state and creates or restores a conversation, then activates it.
initialize_history_manager(persist = FALSE)initialize_history_manager(persist = FALSE)
persist |
Logical. Restore and save local gadget history? |
Character: ID of the created conversation.
Has the conversation started (model locked)?
is_conversation_started(id)is_conversation_started(id)
id |
Conversation ID. |
Logical.
Launch PacketLLM from the RStudio Addins menu
packetllm_addin()packetllm_addin()
Value passed to run_llm_chat_app().
This function processes a character string specifying a page range (e.g., "1-3,5") and returns a numeric vector containing the individual page numbers, sorted and unique.
parse_pages(pages_str)parse_pages(pages_str)
pages_str |
Character string specifying pages, e.g., "1-3,5". |
A numeric vector containing the unique page numbers specified in the
input string, sorted in ascending order. Returns an empty integer vector
if the input string is empty or contains only whitespace. Stops with an
error if the input pages_str is not a single character string or if the
format within the string is invalid (e.g., non-numeric parts, invalid ranges).
# Example 1: Simple range and single page page_string1 <- "1-3, 5" parsed_pages1 <- parse_pages(page_string1) print(parsed_pages1) # Output: [1] 1 2 3 5 # Example 2: Multiple ranges and single pages, with spaces and duplicates page_string2 <- " 2, 4-6, 9 , 11-12, 5 " parsed_pages2 <- parse_pages(page_string2) print(parsed_pages2) # Output: [1] 2 4 5 6 9 11 12 (sorted, unique) # Example 3: Single number page_string3 <- "10" parsed_pages3 <- parse_pages(page_string3) print(parsed_pages3) # Output: [1] 10 # Example 4: Empty string input page_string_empty <- "" parsed_pages_empty <- parse_pages(page_string_empty) print(parsed_pages_empty) # Output: integer(0) # Example 5: Invalid input (non-numeric) - demonstrates error handling page_string_invalid <- "1-3, five" ## Not run: # This will stop with an error message about "five" tryCatch(parse_pages(page_string_invalid), error = function(e) print(e$message)) ## End(Not run) # Example 6: Invalid range format (missing end) - demonstrates error handling page_string_invalid_range <- "1-" ## Not run: # This will stop with an error message about invalid range format tryCatch(parse_pages(page_string_invalid_range), error = function(e) print(e$message)) ## End(Not run) # Example 7: Invalid range format (start > end) - demonstrates error handling page_string_invalid_order <- "5-3" ## Not run: # This will stop with an error message about invalid range values tryCatch(parse_pages(page_string_invalid_order), error = function(e) print(e$message)) ## End(Not run)# Example 1: Simple range and single page page_string1 <- "1-3, 5" parsed_pages1 <- parse_pages(page_string1) print(parsed_pages1) # Output: [1] 1 2 3 5 # Example 2: Multiple ranges and single pages, with spaces and duplicates page_string2 <- " 2, 4-6, 9 , 11-12, 5 " parsed_pages2 <- parse_pages(page_string2) print(parsed_pages2) # Output: [1] 2 4 5 6 9 11 12 (sorted, unique) # Example 3: Single number page_string3 <- "10" parsed_pages3 <- parse_pages(page_string3) print(parsed_pages3) # Output: [1] 10 # Example 4: Empty string input page_string_empty <- "" parsed_pages_empty <- parse_pages(page_string_empty) print(parsed_pages_empty) # Output: integer(0) # Example 5: Invalid input (non-numeric) - demonstrates error handling page_string_invalid <- "1-3, five" ## Not run: # This will stop with an error message about "five" tryCatch(parse_pages(page_string_invalid), error = function(e) print(e$message)) ## End(Not run) # Example 6: Invalid range format (missing end) - demonstrates error handling page_string_invalid_range <- "1-" ## Not run: # This will stop with an error message about invalid range format tryCatch(parse_pages(page_string_invalid_range), error = function(e) print(e$message)) ## End(Not run) # Example 7: Invalid range format (start > end) - demonstrates error handling page_string_invalid_order <- "5-3" ## Not run: # This will stop with an error message about invalid range values tryCatch(parse_pages(page_string_invalid_order), error = function(e) print(e$message)) ## End(Not run)
This function reads the content of a file with the extension .R, .pdf, .docx,
.txt, or .csv and returns it as a single character string.
For PDF files, if the pages parameter is provided, only the selected pages will be read.
For CSV files, the data is converted into a compact, model-friendly Markdown
representation: a short header with the dimensions, a list of columns with
their inferred types, and the rows rendered as a Markdown table. The field
delimiter is detected automatically (comma, semicolon, tab, or pipe), and
large files are truncated to the first 1000 rows with an explicit note.
read_file_content(file_path, pages = NULL)read_file_content(file_path, pages = NULL)
file_path |
Character string. Path to the file. |
pages |
Optional. A numeric vector specifying which pages (for PDF) should be read. |
A character string containing the file content, with pages separated by
double newlines for PDF files and CSV data rendered as a Markdown table.
Stops with an error if the file does not
exist, the format is unsupported, or required packages (pdftools for PDF,
readtext for DOCX) are not installed or if pages is not numeric when provided.
# --- Example for reading an R file --- # Create a temporary R file temp_r_file <- tempfile(fileext = ".R") writeLines(c("x <- 1", "print(x + 1)"), temp_r_file) # Read the content r_content <- tryCatch(read_file_content(temp_r_file), error = function(e) e$message) print(r_content) # Clean up the temporary file unlink(temp_r_file) # --- Example for reading a TXT file --- temp_txt_file <- tempfile(fileext = ".txt") writeLines(c("Line one.", "Second line."), temp_txt_file) txt_content <- tryCatch(read_file_content(temp_txt_file), error = function(e) e$message) print(txt_content) unlink(temp_txt_file) # --- Example for reading a CSV file --- temp_csv_file <- tempfile(fileext = ".csv") write.csv(head(mtcars, 3), temp_csv_file, row.names = FALSE) csv_content <- tryCatch(read_file_content(temp_csv_file), error = function(e) e$message) cat(csv_content) unlink(temp_csv_file) # --- Example for PDF (requires pdftools, only run if installed) --- ## Not run: # This part requires the 'pdftools' package and a valid PDF file. # Provide a path to an actual PDF file to test this functionality. # Replace "path/to/your/sample.pdf" with a real path. pdf_file_path <- "path/to/your/sample.pdf" # Check if pdftools is installed and the file exists if (requireNamespace("pdftools", quietly = TRUE) && file.exists(pdf_file_path)) { # Example: Read all pages pdf_content_all <- tryCatch( read_file_content(pdf_file_path), error = function(e) paste("Error reading all pages:", e$message) ) # print(substr(pdf_content_all, 1, 100)) # Print first 100 chars # Example: Read only page 1 pdf_content_page1 <- tryCatch( read_file_content(pdf_file_path, pages = 1), error = function(e) paste("Error reading page 1:", e$message) ) # print(pdf_content_page1) } else if (!requireNamespace("pdftools", quietly = TRUE)) { message("Skipping PDF example: 'pdftools' package not installed.") } else { message("Skipping PDF example: File not found at '", pdf_file_path, "'") } ## End(Not run) # Note: Reading DOCX files is also supported if the 'readtext' package # is installed, but a simple runnable example is difficult to create # without including a sample file or complex setup.# --- Example for reading an R file --- # Create a temporary R file temp_r_file <- tempfile(fileext = ".R") writeLines(c("x <- 1", "print(x + 1)"), temp_r_file) # Read the content r_content <- tryCatch(read_file_content(temp_r_file), error = function(e) e$message) print(r_content) # Clean up the temporary file unlink(temp_r_file) # --- Example for reading a TXT file --- temp_txt_file <- tempfile(fileext = ".txt") writeLines(c("Line one.", "Second line."), temp_txt_file) txt_content <- tryCatch(read_file_content(temp_txt_file), error = function(e) e$message) print(txt_content) unlink(temp_txt_file) # --- Example for reading a CSV file --- temp_csv_file <- tempfile(fileext = ".csv") write.csv(head(mtcars, 3), temp_csv_file, row.names = FALSE) csv_content <- tryCatch(read_file_content(temp_csv_file), error = function(e) e$message) cat(csv_content) unlink(temp_csv_file) # --- Example for PDF (requires pdftools, only run if installed) --- ## Not run: # This part requires the 'pdftools' package and a valid PDF file. # Provide a path to an actual PDF file to test this functionality. # Replace "path/to/your/sample.pdf" with a real path. pdf_file_path <- "path/to/your/sample.pdf" # Check if pdftools is installed and the file exists if (requireNamespace("pdftools", quietly = TRUE) && file.exists(pdf_file_path)) { # Example: Read all pages pdf_content_all <- tryCatch( read_file_content(pdf_file_path), error = function(e) paste("Error reading all pages:", e$message) ) # print(substr(pdf_content_all, 1, 100)) # Print first 100 chars # Example: Read only page 1 pdf_content_page1 <- tryCatch( read_file_content(pdf_file_path, pages = 1), error = function(e) paste("Error reading page 1:", e$message) ) # print(pdf_content_page1) } else if (!requireNamespace("pdftools", quietly = TRUE)) { message("Skipping PDF example: 'pdftools' package not installed.") } else { message("Skipping PDF example: File not found at '", pdf_file_path, "'") } ## End(Not run) # Note: Reading DOCX files is also supported if the 'readtext' package # is installed, but a simple runnable example is difficult to create # without including a sample file or complex setup.
Reset the history manager
reset_history_manager(clear_persistent = FALSE)reset_history_manager(clear_persistent = FALSE)
clear_persistent |
Logical. Delete saved local gadget history too? |
Invisible NULL.
Launches PacketLLM as an RStudio/Shiny gadget. The gadget can use RStudio editor context when available, while still running outside RStudio with reduced functionality.
run_llm_chat_app()run_llm_chat_app()
Value passed to shiny::stopApp() (typically NULL).
## Not run: run_llm_chat_app() ## End(Not run)## Not run: run_llm_chat_app() ## End(Not run)
Set the active conversation
set_active_conversation(id)set_active_conversation(id)
id |
Conversation ID or NULL. |
Invisible NULL.
Set model for conversation (if not started)
set_conversation_model(id, model_name)set_conversation_model(id, model_name)
id |
Conversation ID. |
model_name |
Model name (must be in available_openai_models). |
Logical.
Set system message for conversation
set_conversation_system_message(id, message)set_conversation_system_message(id, message)
id |
Conversation ID. |
message |
Single string system message. |
Logical.