Title: | Interactive 'OpenAI' Model Integration in 'RStudio' |
Version: | 0.1.0 |
Description: | Offers an interactive 'RStudio' gadget interface for communicating with 'OpenAI' large language models (e.g., 'gpt-4o', 'gpt-4o-mini', 'gpt-4.1', 'o1', 'o3-mini') (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 model parameters such as temperature and 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. |
License: | MIT + file LICENSE |
Encoding: | UTF-8 |
RoxygenNote: | 7.3.2 |
URL: | https://github.com/AntoniCzolgowski/PacketLLM |
BugReports: | https://github.com/AntoniCzolgowski/PacketLLM/issues |
Imports: | future, httr, pdftools, promises, readtext, shiny, shinyjs, stats, tools, utils |
Depends: | R (≥ 4.1.0) |
Suggests: | knitr, rmarkdown, testthat (≥ 3.0.0) |
Config/testthat/edition: | 3 |
VignetteBuilder: | knitr |
NeedsCompilation: | no |
Packaged: | 2025-04-22 17:11:58 UTC; anton |
Author: | Antoni Czolgowski [aut, cre] |
Maintainer: | Antoni Czolgowski <antoni.czolgowski@gmail.com> |
Repository: | CRAN |
Date/Publication: | 2025-04-24 17:10:06 UTC |
Adds an attachment to the active conversation
Description
Associates a file's name and content with the currently active conversation. This function prevents adding attachments with duplicate names to the same conversation.
Usage
add_attachment_to_active_conversation(name, content)
Arguments
name |
Character string. The name of the attachment file (e.g., "script.R"). |
content |
Character string. The content of the file as a single string. |
Value
Logical. TRUE
if the attachment (consisting of name
and content
)
was successfully added to the active conversation's attachment list.
FALSE
if no conversation is active, the active conversation doesn't exist
anymore, or if an attachment with the same name
already exists in the
active conversation.
Examples
# Setup
reset_history_manager()
conv_addattach_id <- create_new_conversation(activate = TRUE)
# Add a first attachment
result1 <- add_attachment_to_active_conversation("report.txt", "Summary of findings.")
print(paste("Added first attachment:", result1)) # TRUE
print("Attachments after first add:")
print(get_active_conversation_attachments())
# Add a second, different attachment
result2 <- add_attachment_to_active_conversation("code.R", "x <- function(y) { y + 1 }")
print(paste("Added second attachment:", result2)) # TRUE
print("Attachments after second add:")
print(get_active_conversation_attachments())
# Try adding an attachment with the same name (should fail)
result3 <- add_attachment_to_active_conversation("report.txt", "Updated summary.")
print(paste("Added duplicate name attachment:", result3)) # FALSE
print("Attachments after duplicate attempt:")
print(get_active_conversation_attachments()) # Should be unchanged
# Try adding when no conversation is active
set_active_conversation(NULL)
result4 <- add_attachment_to_active_conversation("another.txt", "Content")
print(paste("Added attachment when none active:", result4)) # FALSE
# Clean up
reset_history_manager()
Adds a message to the active conversation's history
Description
Appends a message with the specified role and content to the history list of the currently active conversation. Handles automatic title generation on the first user message and locks the conversation model upon adding the first assistant message.
Usage
add_message_to_active_history(role, content)
Arguments
role |
Character string. The role of the message author, must be one of "user", "assistant", or "system". |
content |
Character string. The content of the message. |
Value
A list indicating the result of the operation. Possible structures:
- list(type = "title_set", new_title = "...")
: If this was the first
user message and the title was automatically set.
- list(type = "assistant_locked_model")
: If this was the first assistant
message, causing the model to be locked.
- list(type = "message_added")
: If a message was added without
triggering title setting or model locking.
- list(type = "error", message = "...")
: If an error occurred (e.g.,
no active conversation, invalid role, conversation vanished).
Examples
# Setup
reset_history_manager()
conv_add_id <- create_new_conversation(activate = TRUE, title = "Initial Title")
# Add first user message (should set title)
result1 <- add_message_to_active_history(role = "user", content = "This is the very first post.")
print("Result after first user message:")
print(result1)
print(paste("New Title:", get_conversation_title(conv_add_id)))
# Add another user message (should just add message)
result2 <- add_message_to_active_history(role = "user", content = "Another question.")
print("Result after second user message:")
print(result2)
# Add first assistant message (should lock model)
result3 <- add_message_to_active_history(role = "assistant", content = "Here is the answer.")
print("Result after first assistant message:")
print(result3)
print(paste("Is model locked?", is_conversation_started(conv_add_id)))
# Add system message (just adds message)
result4 <- add_message_to_active_history(role = "system", content = "System notification.")
print("Result after system message:")
print(result4)
# Check final history
print("Final history:")
print(get_conversation_history(conv_add_id))
# Clean up
reset_history_manager()
Add user message to the active conversation Calls add_message_to_active_history, which handles model locking and title setting.
Description
Add user message to the active conversation Calls add_message_to_active_history, which handles model locking and title setting.
Usage
add_user_message(text)
Arguments
text |
The user's message text (a single character string). |
Value
Invisible NULL
(invisible(NULL)
). This function is called for its
side effect of adding a message to the conversation history.
Stops with an error if text
is not a single character string.
Examples
# This example modifies the internal state managed by history_manager.
# Ensure history_manager is initialized if running standalone.
# Setup: Create and activate a conversation
conv_id_user <- tryCatch(create_new_conversation(activate = TRUE), error = function(e) NULL)
if (!is.null(conv_id_user)) {
# Add a message from the user
add_user_message("Hello, this is my first message.")
# Verify the message was added (optional)
history <- get_active_chat_history()
print(tail(history, 1)) # Show the last message
# Clean up the conversation
delete_conversation(conv_id_user)
} else {
print("Skipping example as conversation setup failed.")
}
# Reset active conversation if needed
set_active_conversation(NULL)
List of available OpenAI models for selection in the UI
Description
List of available OpenAI models for selection in the UI
Usage
available_openai_models
Format
An object of class character
of length 5.
Call OpenAI API
Description
Function sends the conversation history to the OpenAI API and returns the model's response.
For models in simplified_models_list
, it does NOT send the temperature
parameter.
Usage
call_openai_chat(messages, model, temperature = 0.5)
Arguments
messages |
List of messages (each message is a list with 'role' and 'content' fields). |
model |
OpenAI model to use. |
temperature |
Temperature parameter (used only for models that support it). |
Value
Character string containing the model's response text, or NULL
if the
response structure is unexpected. If an API or HTTP error occurs,
the function stops execution with an error message.
Examples
## Not run:
# This example requires the OPENAI_API_KEY environment variable to be set
# and requires internet access to reach the OpenAI API.
# Before running, ensure the key is set, e.g., using:
# Sys.setenv(OPENAI_API_KEY = "your_actual_openai_api_key")
# Remember to replace "your_actual_openai_api_key" with your real key.
# 1. Define the conversation history
example_messages <- list(
list(role = "system", content = "You are a helpful assistant providing concise answers."),
list(role = "user", content = "What is the main purpose of the 'httr' package in R?")
)
# 2. Choose a model (ensure it's in available_openai_models)
selected_model <- "gpt-4o-mini" # Supports temperature
# 3. Call the API using tryCatch for safety
api_response <- tryCatch({
call_openai_chat(
messages = example_messages,
model = selected_model,
temperature = 0.7
)
}, error = function(e) {
# Handle potential errors (API key missing, network issues, API errors)
paste("API call failed:", e$message)
})
# 4. Print the response (or error message)
print(api_response)
# Example with a simplified model (omits temperature)
selected_model_simple <- "o3-mini" # Does not support temperature
# Check if this model is actually available in your package installation
if(selected_model_simple %in% PacketLLM::available_openai_models) {
api_response_simple <- tryCatch({
call_openai_chat(
messages = example_messages,
model = selected_model_simple
# Temperature argument is ignored internally by the function
)
}, error = function(e) {
paste("API call failed:", e$message)
})
print(api_response_simple)
} else {
# Use message() for console output that can be suppressed if needed
message(paste("Skipping simplified model example:",
selected_model_simple, "not in available_openai_models."))
}
## End(Not run)
Check API Key
Description
This function checks if the API key assigned to the OPENAI_API_KEY
variable
exists in the environment variables (e.g., in the .Renviron file).
If the key is not set, the function will raise an error and stop execution.
If the key is set, it returns TRUE invisibly.
Usage
check_api_key()
Value
Invisible TRUE
(invisible(TRUE)
) if the API key is set.
Otherwise, stops execution with an error.
Examples
## Not run:
# This function requires the OPENAI_API_KEY environment variable to be set.
# You can check if the key is set using Sys.getenv("OPENAI_API_KEY").
# If the key is set, calling check_api_key() will return TRUE invisibly.
# If the key is NOT set, it will stop execution with an error message.
# Example demonstrating how to handle the potential error if the key is missing:
result <- tryCatch({
check_api_key()
"API key found." # Message if check passes
}, error = function(e) {
# Handle the error if the key is missing
paste("Error:", e$message)
})
print(result)
## End(Not run)
Creates a new conversation
Description
Adds a new, empty conversation structure to the internal history store. Optionally sets the new conversation as the active one.
Usage
create_new_conversation(
activate = FALSE,
add_initial_settings = TRUE,
title = NULL
)
Arguments
activate |
Logical. Should the new conversation be set as active immediately? (Default: |
add_initial_settings |
Logical. Should default settings (model, temperature,
system message) be added to the conversation structure? (Default: |
title |
Character string or |
Value
Character string. The unique ID assigned to the newly created conversation.
Examples
# Ensure manager is initialized (or reset)
reset_history_manager()
initialize_history_manager() # Creates one initial conversation
initial_active_id <- get_active_conversation_id()
# Create a new conversation without activating it
conv1_id <- create_new_conversation(activate = FALSE, title = "My First Topic")
print(paste("Created conv1 ID:", conv1_id))
current_active_id <- get_active_conversation_id() # Should still be the initial one
print(paste("Active ID:", current_active_id))
# Create another conversation and activate it immediately
conv2_id <- create_new_conversation(activate = TRUE, title = "My Second Topic")
print(paste("Created conv2 ID:", conv2_id))
current_active_id_2 <- get_active_conversation_id() # Should be conv2_id now
print(paste("Active ID:", current_active_id_2))
# Check total conversations
total_convs <- length(get_all_conversation_ids())
print(paste("Total conversations:", total_convs))
# Clean up by resetting (which deletes all)
reset_history_manager()
Deletes the conversation with the given ID
Description
Removes the specified conversation from the internal history store. If the
deleted conversation was the active one, the active conversation ID is reset
to NULL
.
Usage
delete_conversation(id)
Arguments
id |
Character string. The ID of the conversation to delete. |
Value
Logical. TRUE
if the conversation was found and successfully deleted.
FALSE
if no conversation with the specified id
existed.
Examples
# Setup
reset_history_manager()
conv_del_id1 <- create_new_conversation(activate = FALSE, title = "To Delete")
conv_del_id2 <- create_new_conversation(activate = TRUE, title = "To Keep Active")
all_ids_before_del <- get_all_conversation_ids()
print(paste("Initial conversations:", paste(all_ids_before_del, collapse=", ")))
print(paste("Initial active ID:", get_active_conversation_id()))
# Delete the non-active conversation
deleted1 <- delete_conversation(conv_del_id1)
print(paste("Deleted conv_del_id1:", deleted1))
all_ids_after_del1 <- get_all_conversation_ids()
print(paste("Conversations after delete 1:", paste(all_ids_after_del1, collapse=", ")))
print(paste("Active ID after delete 1:", get_active_conversation_id())) # Should be unchanged
# Delete the active conversation
deleted2 <- delete_conversation(conv_del_id2)
print(paste("Deleted conv_del_id2:", deleted2))
all_ids_after_del2 <- get_all_conversation_ids() # Should be empty now
# MODIFIED LINE (was too long)
print(paste("Conversations after delete 2:", paste(all_ids_after_del2, collapse=", ")))
print(paste("Active ID after delete 2:", get_active_conversation_id())) # Should be NULL
# Try deleting a non-existent conversation
deleted3 <- delete_conversation("conv_non_existent")
print(paste("Deleted non-existent:", deleted3)) # FALSE
# Clean up
reset_history_manager()
Gets the chat history for the active conversation
Description
Retrieves the list of messages associated with the currently active conversation.
Usage
get_active_chat_history()
Value
List. A list containing the message history (each element is a list
with role
and content
) for the currently active conversation.
Returns an empty list (list()
) if no conversation is active or if
the active conversation has no history yet.
Examples
# Setup
reset_history_manager()
conv_hist_id <- create_new_conversation(activate = TRUE)
# Get history when empty
print("Initial history:")
print(get_active_chat_history()) # list()
# Add messages
add_message_to_active_history("user", "Question 1")
add_message_to_active_history("assistant", "Answer 1")
# Get history after adding messages
print("History after messages:")
print(get_active_chat_history())
# Deactivate and check (should be empty list)
set_active_conversation(NULL)
print("History when none active:")
print(get_active_chat_history()) # list()
# Clean up
reset_history_manager()
Gets the full object of the active conversation
Description
Retrieves the complete data structure (a list) associated with the currently active conversation.
Usage
get_active_conversation()
Value
List or NULL
. A list containing all data for the active conversation
(id, title, history, attachments, settings, etc.), or NULL
if no
conversation is currently active.
Examples
# Setup
reset_history_manager()
conv_get_obj_id <- create_new_conversation(activate = TRUE, title = "Test Object")
add_message_to_active_history("user", "Message for object test")
# Get the active conversation object
active_obj <- get_active_conversation()
if (!is.null(active_obj)) {
print("Active conversation object:")
print(str(active_obj)) # Use str() for concise structure view
} else {
print("No active conversation found.")
}
# Deactivate and try again
set_active_conversation(NULL)
active_obj_null <- get_active_conversation()
print(paste("Active object when none active:", is.null(active_obj_null))) # TRUE
# Clean up
reset_history_manager()
Gets the list of attachments for the active conversation
Description
Retrieves the list of attachments (files provided as context) associated with the currently active conversation.
Usage
get_active_conversation_attachments()
Value
List. A list where each element is a list containing name
(character)
and content
(character) for an attachment associated with the currently
active conversation. Returns an empty list (list()
) if no conversation
is active or if the active conversation has no attachments.
Examples
# Setup
reset_history_manager()
conv_getactiveattach_id <- create_new_conversation(activate = TRUE)
# Get attachments when none added
print("Attachments initially:")
print(get_active_conversation_attachments()) # list()
# Add some attachments
add_attachment_to_active_conversation("data.csv", "col1,col2\n1,2")
add_attachment_to_active_conversation("notes.txt", "Reminder")
# Get attachments again
print("Attachments after adding:")
attachments_list <- get_active_conversation_attachments()
print(attachments_list)
print(paste("Number of attachments:", length(attachments_list))) # 2
# Deactivate and check (should be empty list)
set_active_conversation(NULL)
print("Attachments when none active:")
print(get_active_conversation_attachments()) # list()
# Clean up
reset_history_manager()
Gets the ID of the active conversation
Description
Retrieves the identifier of the conversation currently marked as active.
Usage
get_active_conversation_id()
Value
Character string or NULL
. The ID of the currently active conversation,
or NULL
if no conversation is active or if the previously active
conversation ID points to a conversation that no longer exists.
Examples
# Setup
reset_history_manager()
conv_get_id <- create_new_conversation(activate = FALSE)
# Check when no conversation is active
print(paste("Active ID initially:", get_active_conversation_id())) # NULL
# Activate the conversation
set_active_conversation(conv_get_id)
# Get the active ID
print(paste("Active ID after set:", get_active_conversation_id())) # conv_get_id
# Deactivate
set_active_conversation(NULL)
print(paste("Active ID after unset:", get_active_conversation_id())) # NULL
# Clean up
reset_history_manager()
Gets a list of IDs of all existing conversations
Description
Retrieves the unique identifiers for all conversations currently stored in the manager.
Usage
get_all_conversation_ids()
Value
Character vector. A vector containing the unique IDs of all currently
stored conversations. Returns an empty character vector (character(0)
)
if no conversations exist.
Examples
# Setup
reset_history_manager()
initial_ids <- get_all_conversation_ids() # Should be character(0)
# MODIFIED LINE (was too long)
print(paste("IDs initially:", paste(initial_ids, collapse=",")))
# Create conversations
conv_all_id1 <- create_new_conversation()
conv_all_id2 <- create_new_conversation()
# Get all IDs
all_ids <- get_all_conversation_ids()
print(paste("IDs after creation:", paste(all_ids, collapse=",")))
print(paste("Number of conversations:", length(all_ids))) # 2
# Delete one and check again
delete_conversation(conv_all_id1)
ids_after_del <- get_all_conversation_ids() # Only ID2
print(paste("IDs after deletion:", paste(ids_after_del, collapse=",")))
# Clean up
reset_history_manager()
Get assistant response for the active conversation
Description
Sends the prepared history (including system message and attachments for standard models) to the OpenAI API and returns the assistant's response. Handles model-specific logic internally.
Usage
get_assistant_response()
Value
Character string. Contains the assistant's response text. If an error occurs during message preparation or the API call, a descriptive error message (starting with "Error:" or "API Error:") is returned instead. Returns "Critical Error: No active conversation..." if no conversation is active.
Examples
## Not run:
# This function requires an active conversation with history,
# the OPENAI_API_KEY environment variable to be set, and internet access.
# Setup: Create, activate, and add a user message
conv_id_resp <- tryCatch(create_new_conversation(activate = TRUE), error = function(e) NULL)
if (!is.null(conv_id_resp)) {
add_user_message("What day is it today?") # Add a user message first
# Ensure the API key is set in your environment before running:
# Sys.setenv(OPENAI_API_KEY = "your_actual_openai_api_key")
# Get the response from the assistant
# For less console output during standard use, you can set the global option:
# options(PacketLLM.verbose = FALSE)
assistant_reply <- get_assistant_response()
# options(PacketLLM.verbose = TRUE) # Optionally set back for debugging
# Print the response
print(assistant_reply)
# Verify the assistant's response was added to history (optional)
# print(get_active_chat_history())
# Clean up
delete_conversation(conv_id_resp)
set_active_conversation(NULL)
} else {
print("Skipping example as conversation setup failed.")
}
## End(Not run)
Gets the list of attachments for the conversation with the given ID
Description
Retrieves the list of attachments (files provided as context) associated with a specific conversation ID.
Usage
get_conversation_attachments(id)
Arguments
id |
Character string. The ID of the conversation. |
Value
List or NULL
. A list where each element is itself a list containing
name
(character) and content
(character) for an attachment
associated with the conversation specified by id
. Returns NULL
if
the conversation does not exist. Returns an empty list (list()
) if
the conversation exists but has no attachments.
Examples
# Setup
reset_history_manager()
conv_attach_id <- create_new_conversation(activate = TRUE)
# Get attachments for new conversation (empty list)
print("Initial attachments by ID:")
print(get_conversation_attachments(conv_attach_id)) # list()
# Add an attachment using the exported function
add_attachment_to_active_conversation("file1.txt", "File content here")
# Get attachments again
print("Attachments after adding:")
print(get_conversation_attachments(conv_attach_id))
# Get attachments for non-existent ID
print("Attachments for non-existent:")
print(get_conversation_attachments("bad_id")) # NULL
# Clean up
reset_history_manager()
Gets the full conversation data object for the given ID
Description
Retrieves the complete data structure (a list) associated with a specific conversation ID, including its history, attachments, settings, etc.
Usage
get_conversation_data(id)
Arguments
id |
Character string. The ID of the conversation. |
Value
List or NULL
. A list containing all stored data associated with the
conversation specified by id
. Returns NULL
if the conversation
does not exist.
Examples
# Setup
reset_history_manager()
conv_getdata_id <- create_new_conversation(title = "Data Test")
set_conversation_temperature(conv_getdata_id, 0.9)
# Get conversation data by ID
data_obj <- get_conversation_data(conv_getdata_id)
if (!is.null(data_obj)) {
print("Conversation data object:")
print(str(data_obj))
}
# Get data for non-existent ID
print("Data for non-existent:")
print(get_conversation_data("bad_id")) # NULL
# Clean up
reset_history_manager()
Gets the chat history for the conversation with the given ID
Description
Retrieves the list of messages associated with a specific conversation ID.
Usage
get_conversation_history(id)
Arguments
id |
Character string. The ID of the conversation. |
Value
List or NULL
. A list containing the message history (each element is a
list with role
and content
) for the conversation specified by id
.
Returns NULL
if the conversation does not exist. Returns an empty list
(list()
) if the conversation exists but has no history yet.
Examples
# Setup
reset_history_manager()
conv_gethist_id <- create_new_conversation(activate = TRUE)
# Get history for new conversation
print("Initial history by ID:")
print(get_conversation_history(conv_gethist_id)) # list()
# Add messages using the exported function
add_message_to_active_history("user", "Hi there")
add_message_to_active_history("assistant", "Hello")
# Get history again
print("History after messages:")
print(get_conversation_history(conv_gethist_id))
# Get history for non-existent ID
print("History for non-existent:")
print(get_conversation_history("bad_id")) # NULL
# Clean up
reset_history_manager()
Gets the model name for the conversation with the given ID
Description
Retrieves the name of the language model assigned to a specific conversation.
Usage
get_conversation_model(id)
Arguments
id |
Character string. The ID of the conversation. |
Value
Character string or NULL
. The name of the OpenAI model assigned to the
conversation with the specified id
. Returns NULL
if the conversation
does not exist. Returns a fallback model name if the model field happens
to be NULL
internally.
Examples
# Setup
reset_history_manager()
conv_model_id <- create_new_conversation() # Uses default model from initialization
# Get the model for the conversation
model_name <- get_conversation_model(conv_model_id)
print(paste("Model for conversation:", model_name))
# Check a non-existent conversation
print(paste("Model for non-existent:", get_conversation_model("bad_id"))) # NULL
# Clean up
reset_history_manager()
Gets the title of the conversation with the given ID
Description
Retrieves the title associated with a specific conversation ID.
Usage
get_conversation_title(id)
Arguments
id |
Character string. The ID of the conversation whose title is requested. |
Value
Character string or NULL
. The title of the conversation associated
with the specified id
. Returns NULL
if the conversation does not exist.
Returns a placeholder string like ‘[No Title - ID: ...]’ if the title
field happens to be NULL
internally (should not normally occur).
Examples
# Setup
reset_history_manager()
conv_title_id1 <- create_new_conversation(title = "Specific Title")
conv_title_id2 <- create_new_conversation() # Default title generated
# Get title by ID
print(paste("Title for ID1:", get_conversation_title(conv_title_id1)))
print(paste("Title for ID2:", get_conversation_title(conv_title_id2)))
# Get title for non-existent ID
print(paste("Title for non-existent:", get_conversation_title("bad_id"))) # NULL
# Clean up
reset_history_manager()
Initializes the history manager
Description
Clears the current history state (all conversations and settings) and creates a single new, empty conversation, setting it as the active conversation. Optionally prints a message to the console in interactive sessions.
Usage
initialize_history_manager()
Value
Character string. The ID of the first, automatically created conversation after initialization.
Examples
# Initialize the manager. A message might appear in the console if run interactively.
first_conv_id <- initialize_history_manager()
print(paste("First conversation ID:", first_conv_id))
# Verify initialization
active_id_after_init <- get_active_conversation_id() # Should be first_conv_id
print(paste("Active ID after init:", active_id_after_init))
all_ids_after_init <- get_all_conversation_ids() # Should have 1 element
print(paste("Total conversations after init:", length(all_ids_after_init)))
# Clean up (reset state for other examples if needed)
reset_history_manager()
Checks if the conversation has started (model locked)
Description
Determines if the model for a given conversation is locked, which typically occurs after the first assistant message has been added. Once locked, the model for the conversation usually cannot be changed.
Usage
is_conversation_started(id)
Arguments
id |
Character string. The ID of the conversation to check. |
Value
Logical. TRUE
if the model for the conversation is locked,
FALSE
otherwise or if the conversation with the specified id
does not exist.
Examples
# Setup
reset_history_manager()
conv_lock_id <- create_new_conversation(activate = TRUE)
# Check status of a new conversation (should be FALSE)
print(paste("Locked initially:", is_conversation_started(conv_lock_id)))
# Add a user message (does NOT lock the model)
add_message_to_active_history(role = "user", content = "First message")
print(paste("Locked after user msg:", is_conversation_started(conv_lock_id)))
# Add an assistant message (using the internal function locks the model)
add_message_to_active_history(role = "assistant", content = "Assistant reply")
# Check status after assistant message (should be TRUE)
print(paste("Locked after assistant msg:", is_conversation_started(conv_lock_id)))
# Check non-existent conversation
print(paste("Locked for non-existent:", is_conversation_started("conv_non_existent"))) # FALSE
# Clean up
reset_history_manager()
Parse page range
Description
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.
Usage
parse_pages(pages_str)
Arguments
pages_str |
Character string specifying pages, e.g., "1-3,5". |
Value
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).
Examples
# 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)
Read file content
Description
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.
Usage
read_file_content(file_path, pages = NULL)
Arguments
file_path |
Character string. Path to the file. |
pages |
Optional. A numeric vector specifying which pages (for PDF) should be read. |
Value
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.
Examples
# --- 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.
Resets the entire state of the history manager
Description
Clears all stored conversations, resets the active conversation ID to NULL
,
and resets the internal conversation counter used for generating IDs.
Effectively returns the manager to its initial empty state. Optionally prints a message
to the console in interactive sessions.
Usage
reset_history_manager()
Value
Invisible NULL
(invisible(NULL)
). Called for its side effect of
clearing the history state.
Examples
# Setup: Initialize and add some data
reset_history_manager() # Ensure clean start
initialize_history_manager()
conv_reset_id <- create_new_conversation(activate = TRUE)
add_message_to_active_history("user", "Message before reset")
# MODIFIED LINE (was too long)
conv_count_before <- length(get_all_conversation_ids()) # Should be 2 initially
print(paste("Conversations before reset:", conv_count_before))
print(paste("Active ID before reset:", get_active_conversation_id())) # ID of conv_reset_id
# Reset the manager. A message might appear in the console if run interactively.
reset_history_manager()
# Verify state after reset
print(paste("Conversations after reset:", length(get_all_conversation_ids()))) # 0
print(paste("Active ID after reset:", get_active_conversation_id())) # NULL
# Note: After reset, you might need to initialize again if needed for subsequent operations
# initialize_history_manager()
Run the LLM Chat Application in RStudio Window
Description
Launches the Shiny application as a Gadget in the RStudio Viewer pane, from where it can be opened in a separate window ("Show in new window"). The application allows interaction with LLM models, managing conversations, attachments, and settings, without blocking the RStudio console when opened in a new window.
Usage
run_llm_chat_app()
Value
Returns the value passed to shiny::stopApp()
when the application is closed (typically NULL
). The primary purpose is the side effect of launching the interactive application.
Examples
## Not run:
# This function launches an interactive Shiny gadget.
# It should be run in an interactive R session, preferably within RStudio.
# Ensure necessary setup like the OpenAI API key environment variable
# might be needed for the application's full functionality once launched.
# Example: Sys.setenv(OPENAI_API_KEY = "your_actual_openai_api_key")
# Launch the application
run_llm_chat_app()
# The application will open in the RStudio Viewer or a separate window.
# Interaction happens within the app's UI.
# To stop the app, close its window or click the 'X' button in the app's UI.
## End(Not run)
Sets the active conversation
Description
Designates a conversation, specified by its ID, as the currently active one.
Setting id
to NULL
deactivates any currently active conversation.
Usage
set_active_conversation(id)
Arguments
id |
Character string (the ID of the conversation to activate) or |
Value
Invisible NULL
(invisible(NULL)
). This function is called for its
side effect of changing the active conversation state. It produces a
warning if attempting to activate a non-existent conversation ID.
Examples
# Setup
reset_history_manager()
conv_set_id1 <- create_new_conversation(activate = FALSE, title = "Conv 1")
conv_set_id2 <- create_new_conversation(activate = FALSE, title = "Conv 2")
print(paste("Initial active ID:", get_active_conversation_id())) # NULL
# Set conv1 as active
set_active_conversation(conv_set_id1)
print(paste("Active ID after set 1:", get_active_conversation_id())) # conv_set_id1
# Set conv2 as active
set_active_conversation(conv_set_id2)
print(paste("Active ID after set 2:", get_active_conversation_id())) # conv_set_id2
# Set non-existent ID (should warn and not change active ID)
set_active_conversation("conv_non_existent")
active_after_invalid_set <- get_active_conversation_id() # Still conv_set_id2
print(paste("Active ID after set non-existent:", active_after_invalid_set))
# Deactivate by setting to NULL
set_active_conversation(NULL)
print(paste("Active ID after set NULL:", get_active_conversation_id())) # NULL
# Clean up
reset_history_manager()
Sets the model for the conversation, if it hasn't started
Description
Assigns a specified OpenAI language model to a conversation, but only if the
conversation exists and has not yet "started" (i.e., no assistant messages
have been added, is_conversation_started(id)
is FALSE
). The model name
must be one of the available models listed in available_openai_models
.
Usage
set_conversation_model(id, model_name)
Arguments
id |
Character string. The ID of the conversation. |
model_name |
Character string. The name of the new model (must be one of
|
Value
Logical. TRUE
if the model was successfully set for the conversation.
FALSE
if the conversation does not exist, the conversation has already
started (model is locked), or the model_name
is not valid/available.
Examples
# Setup
reset_history_manager()
conv_set_model_id <- create_new_conversation(activate = TRUE)
print(paste("Initial model:", get_conversation_model(conv_set_model_id)))
# Set a new valid model (use a known available model)
# Ensure the model exists in PacketLLM::available_openai_models
target_model <- "gpt-4o-mini" # Assuming this is usually available
if (target_model %in% PacketLLM::available_openai_models) {
result_set <- set_conversation_model(conv_set_model_id, target_model)
print(paste("Model set successful:", result_set))
print(paste("Model after set:", get_conversation_model(conv_set_model_id)))
} else {
message(paste("Skipping set model example: Target model", target_model, "not in list."))
}
# Try setting an invalid model name
result_invalid <- set_conversation_model(conv_set_model_id, "invalid-model-name")
print(paste("Invalid model set successful:", result_invalid)) # FALSE
model_after_invalid <- get_conversation_model(conv_set_model_id) # Unchanged
print(paste("Model after invalid set:", model_after_invalid))
# Simulate conversation start by adding an assistant message
add_message_to_active_history("user", "Lock question")
add_message_to_active_history("assistant", "Lock answer") # This locks it
# Try setting model after lock (should fail)
result_locked <- set_conversation_model(conv_set_model_id, "gpt-4o") # Try setting back
print(paste("Model set after lock successful:", result_locked)) # FALSE
model_after_locked <- get_conversation_model(conv_set_model_id) # Unchanged
print(paste("Model after locked attempt:", model_after_locked))
# Clean up
reset_history_manager()
Sets the system message for the conversation with the given ID
Description
Updates the system message (instructions provided to the language model) for a specific conversation.
Usage
set_conversation_system_message(id, message)
Arguments
id |
Character string. The ID of the conversation. |
message |
Character string. The new system message content (must be a single string). |
Value
Logical. TRUE
if the system message was successfully updated. FALSE
if the conversation does not exist or if the provided message
is not a
single character string.
Examples
# Setup
reset_history_manager()
conv_sys_id <- create_new_conversation()
initial_sys_msg <- get_conversation_data(conv_sys_id)$system_message
print(paste("Initial system message:", initial_sys_msg)) # Default message
# Set a valid system message
new_message <- "You are an expert R programmer. Respond only with code."
result_valid <- set_conversation_system_message(conv_sys_id, new_message)
print(paste("Valid set successful:", result_valid)) # TRUE
msg_after_set <- get_conversation_data(conv_sys_id)$system_message
print(paste("System message after set:", msg_after_set))
# Try setting an invalid message (e.g., not a single string)
result_invalid <- set_conversation_system_message(conv_sys_id, list("not a string"))
print(paste("Invalid set successful:", result_invalid)) # FALSE
# Try setting an invalid message (vector of strings)
result_invalid_vec <- set_conversation_system_message(conv_sys_id, c("Line 1", "Line 2"))
print(paste("Invalid vector set successful:", result_invalid_vec)) # FALSE
# Check message after invalid attempts
final_msg_after_invalid <- get_conversation_data(conv_sys_id)$system_message # Unchanged
print(paste("System message after invalid attempts:", final_msg_after_invalid))
# Clean up
reset_history_manager()
Sets the temperature for the conversation with the given ID
Description
Updates the temperature setting (controls creativity/randomness of responses) for a specific conversation.
Usage
set_conversation_temperature(id, temperature)
Arguments
id |
Character string. The ID of the conversation. |
temperature |
Numeric. The new temperature value, must be a single number between 0 and 1 (inclusive). |
Value
Logical. TRUE
if the temperature was successfully updated. FALSE
if
the conversation does not exist or if the provided temperature
value
is invalid (not a single number between 0 and 1).
Examples
# Setup
reset_history_manager()
conv_temp_id <- create_new_conversation()
initial_temp <- get_conversation_data(conv_temp_id)$temperature
print(paste("Initial temperature:", initial_temp)) # Default temp
# Set a valid temperature
result_valid <- set_conversation_temperature(conv_temp_id, 0.85)
print(paste("Valid set successful:", result_valid)) # TRUE
temp_after_valid <- get_conversation_data(conv_temp_id)$temperature # 0.85
print(paste("Temp after valid set:", temp_after_valid))
# Set an invalid temperature (outside 0-1)
result_invalid <- set_conversation_temperature(conv_temp_id, 1.5)
print(paste("Invalid set successful:", result_invalid)) # FALSE
# MODIFIED LINE (was too long)
temp_after_invalid <- get_conversation_data(conv_temp_id)$temperature # Unchanged (0.85)
print(paste("Temp after invalid set:", temp_after_invalid))
# Set an invalid temperature (wrong type)
result_invalid_type <- set_conversation_temperature(conv_temp_id, "high")
print(paste("Invalid type set successful:", result_invalid_type)) # FALSE
# Try on non-existent ID
result_bad_id <- set_conversation_temperature("bad_id", 0.5)
print(paste("Set on bad ID successful:", result_bad_id)) # FALSE
# Clean up
reset_history_manager()