| Title: | Interactive 'OpenAI' Model Integration in 'RStudio' |
|---|---|
| Description: | Offers an interactive 'RStudio' gadget interface for communicating with 'OpenAI' large language models (e.g., 'gpt-5', 'gpt-5-mini', 'gpt-5-nano') (<https://platform.openai.com/docs/api-reference>). Enables users to conduct multiple chat conversations simultaneously in separate tabs. Supports uploading local files (R, PDF, DOCX) to provide context for the models. Allows per-conversation configuration of system messages (where supported by the model). API interactions via the 'httr' package are performed asynchronously using 'promises' and 'future' to avoid blocking the R console. Useful for tasks like code generation, text summarization, and document analysis directly within the 'RStudio' environment. Requires an 'OpenAI' API key set as an environment variable. |
| Authors: | Antoni Czolgowski [aut, cre] |
| Maintainer: | Antoni Czolgowski <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.1.1 |
| Built: | 2026-05-22 18:53:53 UTC |
| Source: | https://github.com/antoniczolgowski/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.
List of available OpenAI models for selection in the UI
available_openai_modelsavailable_openai_models
An object of class character of length 3.
Sends messages to the OpenAI Chat Completions API and returns the assistant content. Temperature is not sent; models run with API defaults.
call_openai_chat(messages, model)call_openai_chat(messages, model)
messages |
List of messages (each a list with 'role' and 'content'). |
model |
OpenAI model to use. |
Character string with assistant reply, or NULL on unexpected response.
## Not run: msgs <- list( list(role = "system", content = "You are concise."), list(role = "user", content = "What does httr do?") ) call_openai_chat(messages = msgs, model = "gpt-5-mini") ## End(Not run)## Not run: msgs <- list( list(role = "system", content = "You are concise."), list(role = "user", content = "What does httr do?") ) call_openai_chat(messages = msgs, model = "gpt-5-mini") ## End(Not run)
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.
Clears state and creates a single new conversation, then activates it.
initialize_history_manager()initialize_history_manager()
Character: ID of the created conversation.
Has the conversation started (model locked)?
is_conversation_started(id)is_conversation_started(id)
id |
Conversation ID. |
Logical.
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, or .docx
and returns it as a single character string. TXT files are also supported.
For PDF files, if the pages parameter is provided, only the selected pages will be read.
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. 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 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 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()reset_history_manager()
Invisible NULL.
Launches the Shiny application as a Gadget in the RStudio Viewer pane (or a separate window). Interacts with LLM models, managing conversations, attachments, and settings, without blocking the R console when opened in a new window.
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.