Skip to content
Merged
Show file tree
Hide file tree
Changes from 38 commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
4ee39fd
feat: evaluate tool
gadenbuie Nov 25, 2025
ad727b8
feat: Use `new_output_handler()` pattern
gadenbuie Nov 25, 2025
61aa3f3
chore: Add icon, improve name
gadenbuie Nov 25, 2025
b504d5d
chore: document()
gadenbuie Nov 25, 2025
6be186b
feat: Add rich evaluation tool output UI
gadenbuie Nov 26, 2025
ac9fe4e
rename: tool-run.R
gadenbuie Nov 26, 2025
3049d9f
chore: update docs and tools, etc.
gadenbuie Nov 26, 2025
fb9db6b
limit height of source code block
gadenbuie Nov 26, 2025
e081bfa
chore: use class `btw-run-source` instead of `btw-run-code`
gadenbuie Nov 26, 2025
237956b
chore: general fixups and review
gadenbuie Dec 1, 2025
290896f
tests: fix plot image test
gadenbuie Dec 1, 2025
ceec3f7
fix: dial in plot sizing and device
gadenbuie Dec 2, 2025
f2dd119
docs: fix arg
gadenbuie Dec 2, 2025
52cbcb2
feat: Use fansi for ANSI-styled text, drop intermediate plots
gadenbuie Dec 2, 2025
4647aef
feat: Use CSS tied to Bootstrap for ANSI colors
gadenbuie Dec 4, 2025
6223653
chore: Use `.bslib-page-dashboard` class
gadenbuie Dec 5, 2025
83c2b33
feat: Tool is opt-in
gadenbuie Dec 5, 2025
1836910
chore: build ignore local dev things
gadenbuie Dec 5, 2025
0a1b3f2
chore: app styles
gadenbuie Dec 5, 2025
8823282
chore: improve cli settings
gadenbuie Dec 5, 2025
900446e
tests: fix checking of all tools
gadenbuie Dec 5, 2025
ec08f97
chore: Add NEWS item
gadenbuie Dec 5, 2025
57cfd2a
docs: Document and address security implications
gadenbuie Dec 5, 2025
d7f8b6f
chore: use fansi (suggests)
gadenbuie Dec 5, 2025
b52bcc6
Merged origin/main into feat/evaluate-tool
gadenbuie Dec 8, 2025
e3b2169
fix(app): Fix registration of run tool in app
gadenbuie Dec 8, 2025
535d05d
feat(tool-run): return something to the LLM if nothing is printed
gadenbuie Dec 8, 2025
ceef5c2
chore(js): Avoid double definition of custom element
gadenbuie Dec 9, 2025
89fe30c
feat: interleaved source/output
gadenbuie Dec 11, 2025
c26abb9
feat: Add copy source code button
gadenbuie Dec 11, 2025
74ff8ab
chore: fix extra leading/trailing newlines,
gadenbuie Dec 11, 2025
5c8dcb3
chore: clean up tooltips if the result card is removed
gadenbuie Dec 11, 2025
f7694f6
feat: copy code+result in reprex style
gadenbuie Dec 11, 2025
2dd7c1f
chore: copy button icon
gadenbuie Dec 11, 2025
551400a
refactor: pull out icons into a separate file
gadenbuie Dec 11, 2025
cb1022c
chore: Take suggestions about tool instructions
gadenbuie Dec 11, 2025
d3c20e3
chore: hide code copy buttons in output
gadenbuie Dec 11, 2025
42ad141
chore: remove docs for internal function
gadenbuie Dec 11, 2025
f8f6659
tests(tool-run): Fix tests
gadenbuie Dec 12, 2025
48ff48a
chore(tool-run): Tweak tool description prompt
gadenbuie Dec 12, 2025
bcdb006
feat: copy-to-clipboard in positron
gadenbuie Dec 12, 2025
9de80ea
chore: tweak css
gadenbuie Dec 12, 2025
3aa8dab
feat(tool-run): Add option to set plot dimensions/size
gadenbuie Dec 12, 2025
b606290
feat(tool-run): Prevent running R code from changing working dir, opt…
gadenbuie Dec 12, 2025
ed07a84
chore(tool-run): Let model know that wd, opts, envvars are restored
gadenbuie Dec 12, 2025
f9bc896
ci: why isn't duckdb installing via binaries?
gadenbuie Dec 15, 2025
46acc25
ci: try again
gadenbuie Dec 15, 2025
45f6388
ci: install into R_LIBS_SITE
gadenbuie Dec 15, 2025
7ae8024
ci: try again
gadenbuie Dec 15, 2025
5b63e7a
ci: just let it take longer
gadenbuie Dec 15, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .Rbuildignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,5 @@
^scripts$
^\.claude$
^CRAN-SUBMISSION$
^\.prettierrc$
^node_modules$
14 changes: 14 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"organizeImportsSkipDestructiveCodeActions": true,
"singleQuote": false,
"semi": false,
"trailingComma": "all",
"overrides": [
{
"files": "**/*.scss",
"options": {
"printWidth": 150
}
}
]
}
4 changes: 4 additions & 0 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,13 @@ Suggests:
chromote,
DBI,
duckdb,
evaluate,
fansi,
gert,
gh,
htmltools,
pandoc,
ragg,
shiny,
shinychat (>= 0.2.0),
testthat (>= 3.0.0),
Expand Down Expand Up @@ -93,6 +96,7 @@ Collate:
'tool-git.R'
'tool-github.R'
'tool-rstudioapi.R'
'tool-run.R'
'tool-search-packages.R'
'tool-session-package-installed.R'
'tool-sessioninfo.R'
Expand Down
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export(btw_tool_git_log)
export(btw_tool_git_status)
export(btw_tool_github)
export(btw_tool_ide_read_current_editor)
export(btw_tool_run_r)
export(btw_tool_search_package_info)
export(btw_tool_search_packages)
export(btw_tool_session_check_package_installed)
Expand Down
2 changes: 2 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# btw (development version)

* New `btw_tool_run_r()` tool allows LLMs to run R code and to see the output, including of plots. Because this tool lets LLMs run R arbitrary R code in the global environment (which can be great but can also have security implications), it is opt-in and disabled by default. See `?btw_tool_run_r` for more details (#126).

* `btw_tool_docs_help_page()` now uses markdown headings and sections for argument descriptions, rather than a table. This is considerably more token efficient when the argument descriptions have more than one paragraph and can't be converted into a markdown table (@jeanchristophe13v, #123).

* btw now removes large inline base64-encoded images, replacing them with a placeholder containing the image's alt text (@jeanchristophe13v, #119).
Expand Down
8 changes: 6 additions & 2 deletions R/btw_client.R
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ btw_client <- function(
}

btw_client_config <- function(client = NULL, tools = NULL, config = list()) {
config$options <- flatten_config_options(config$options)
# Options should be flattened and btw-prefixed by `read_btw_file()`.
withr::local_options(config$options)

config$tools <-
Expand Down Expand Up @@ -275,7 +275,11 @@ flatten_config_options <- function(opts, prefix = "btw", sep = ".") {
}

for (i in seq_along(x)) {
new_key <- paste(key_prefix, nm[i], sep = sep)
if (nzchar(key_prefix)) {
new_key <- paste(key_prefix, nm[i], sep = sep)
} else {
new_key <- nm[i]
}
recurse(x[[i]], new_key)
}
} else {
Expand Down
27 changes: 22 additions & 5 deletions R/btw_client_app.R
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ btw_app_from_client <- function(client, messages = list(), ...) {
class = "btn-close",
style = "position: fixed; top: 6px; right: 6px;"
),
class = "bslib-page-dashboard",
btw_title(FALSE),
shinychat::chat_mod_ui(
"chat",
Expand All @@ -137,6 +138,13 @@ btw_app_from_client <- function(client, messages = list(), ...) {
.sidebar-collapsed > .main > main .sidebar-title { display: block; }
.bslib-sidebar-layout.sidebar-collapsed>.collapse-toggle { top: 1.8rem; }
.bslib-page-main { gap: 0.5rem; }
aside#tools_sidebar {
box-shadow: 2px 2px 5px rgba(var(--bs-emphasis-color-rgb), 10%);
}
shiny-chat-message .message-icon {
background-color: var(--bs-white);
box-shadow: 2px 2px 5px rgba(var(--bs-emphasis-color-rgb), 10%);
}
"
)),
)
Expand Down Expand Up @@ -215,13 +223,16 @@ btw_app_from_client <- function(client, messages = list(), ...) {
if (!length(selected_tools())) {
client$set_tools(list())
} else {
.btw_tools <- keep(btw_tools(), function(tool) {
tool@name %in% selected_tools()
})
.other_tools <- keep(other_tools, function(tool) {
sel_btw_tools <- btw_tools(
intersect(names(.btw_tools), selected_tools())
)
sel_other_tools <- keep(other_tools, function(tool) {
tool@name %in% selected_tools()
})
client$set_tools(c(.btw_tools, other_tools))
sel_tools <- c(sel_btw_tools, sel_other_tools)
# tool_names <- map_chr(tools, S7::prop, "name")
# cli::cli_inform("Setting {.field client} tools to: {.val {tool_names}}")
client$set_tools(sel_tools)
}
})

Expand Down Expand Up @@ -269,6 +280,10 @@ btw_app_from_client <- function(client, messages = list(), ...) {
save.interface = old_save
))

if (identical(Sys.getenv("BTW_IN_TESTING"), "true")) {
return(list(ui = ui, server = server))
}

app <- shiny::shinyApp(ui, server, ...)
if (getOption("btw.app.in_addin", FALSE)) {
shiny::runApp(app, launch.browser = function(url) {
Expand Down Expand Up @@ -597,10 +612,12 @@ app_tool_group_choice_input <- function(
group,
"docs" = shiny::span(label_icon, "Documentation"),
"env" = shiny::span(label_icon, "Environment"),
"eval" = shiny::span(label_icon, "Code Evaluation"),
"files" = shiny::span(label_icon, "Files"),
"git" = shiny::span(label_icon, "Git"),
"github" = shiny::span(label_icon, "GitHub"),
"ide" = shiny::span(label_icon, "IDE"),
"run" = shiny::span(label_icon, "Run Code"),
"search" = shiny::span(label_icon, "Search"),
"session" = shiny::span(label_icon, "Session Info"),
"web" = shiny::span(label_icon, "Web Tools"),
Expand Down
Loading
Loading