Added three new btw skills CLI commands for
discovering and fetching skills without entering R:
btw skills list <source> lists available skills from
a package or GitHub repository (with --json output
support); btw skills get <source> [names...] fetches
one or more skills by name, or lists them when no names are given (use
--all to fetch all);
btw skills resource <source> <name> <paths...>
fetches individual resource files bundled with a skill. When the source
is a GitHub repository, local path information is omitted from the
output since the temporary download directory is removed when
btw exits. (#199)
btw_app() gains a model_choices
parameter for switching between AI providers and models from the status
bar. Set to "auto" (default) to show named
btw.md client configs when two or more are present,
"btw_md" to always use btw.md configs,
"provider" to browse the active provider’s model list, or
"none" to hide the selector. When switching providers, the
chat history, system prompt, and tools are carried over to the new
client (#196).
The btw_tool_skill tool now supports custom skill
search directories via the btw.skills.paths R option or
BTW_SKILLS_PATHS environment variable. When set, the value
entirely replaces all user-level and project-level skill directories;
package-bundled skills are always preserved. Multiple paths can be
provided as a character vector (R option) or OS-native path-separated
string (env var). Values are captured at tool-registration time, so
custom directories set in btw.md survive after
btw_client() returns (#193).
Added btw_tool_files_patch(), a new files tool that
applies a structured diff-style patch envelope to make coordinated
changes across multiple files in a single call. One patch can add,
update, delete, and rename files atomically: all operations are
validated before any file is written, so a partial failure leaves the
working tree untouched (#190).
The btw info CLI command group has been replaced by
three focused top-level commands: btw system-info (platform
and R session info), btw check-installed <pkgs>
(check if packages are installed, exits 0 by default with
--fail for non-zero exit on missing packages), and
btw installed-packages <pkgs> (show installed package
versions). btw info is retained as a deprecated stub that
prints migration guidance. All three commands support
--json output with documented field shapes (#195).
Added two new commands to the btw CLI:
btw app to launch a btw_app() session in the
current working directory and btw skills install to install
skills from the terminal.
btw skills install . installs skills from all
project dependencies. In packages (directories with a
DESCRIPTION file), Imports and
Suggests are scanned; otherwise
renv::dependencies() is used as a fallback. The same
behaviour is available in R via
btw_skill_install_project().
Added btw docs topics <pkg> to the
btw CLI for discovering a package’s help topics and
vignettes. Use --only help or --only vignettes
to limit output to one section, or --json for
machine-readable output (#195).
Added btw help to the btw CLI, which
prints the r-btw-cli skill — a usage guide designed for AI
agents.
btw_app() is now compatible with and requires
shinychat v0.4.0. Per-block copy buttons and IDE action buttons (insert
at cursor, insert in new file, run in console) are restored for R output
blocks in the new React-based shinychat (#188).
btw_tool_agent_subagent() now correctly uses the
options from your btw.md file when called directly rather
than through btw_client() or btw_app()
(#185).
User-level config locations are now consistent across skills,
agents, and btw.md discovery. Skills installed with btw
v1.2.0 are still discovered for backwards compatibility (#182).
The btw CLI now loads datasets,
utils, stats, and methods by
declaring them in the Rapp #| launcher: frontmatter,
reducing surprises for users who expect standard R packages to be
available (#181).
Several tool groups and tool names have been renamed for clarity (#159):
| Old Name | New Name |
|---|---|
session group |
sessioninfo group |
search group |
cran group |
btw_tool_session_platform_info() |
btw_tool_sessioninfo_platform() |
btw_tool_session_package_info() |
btw_tool_sessioninfo_package() |
btw_tool_session_check_package_installed() |
btw_tool_sessioninfo_is_package_installed() |
btw_tool_search_packages() |
btw_tool_cran_search() |
btw_tool_search_package_info() |
btw_tool_cran_package() |
btw_tool_files_list_files() |
btw_tool_files_list() |
btw_tool_files_read_text_file() |
btw_tool_files_read() |
btw_tool_files_write_text_file() |
btw_tool_files_write() |
btw_tool_files_code_search() |
btw_tool_files_search() |
The old names and group aliases continue to work but emit deprecation
warnings. The btw.files_code_search.extensions and
btw.files_code_search.exclusions options have also been
renamed to btw.files_search.extensions and
btw.files_search.exclusions, with the old option names
emitting deprecation warnings.
New btw CLI provides command-line access to btw’s
tool groups — docs, pkg,
info, and cran — powered by Rapp. Install with
install_btw_cli() and run commands like
btw docs help dplyr::mutate or
btw cran search "tidyverse". Output is designed for
humans and LLMs: colored and formatted for terminals, plain markdown
when piped, with a --json flag to return pipable JSON in
select commands (#176).
btw.md now supports configuring multiple client
options. When btw_client() is called interactively, you’ll
be presented with a menu to choose which client to use. Clients can be
specified as an array:
client:
- anthropic/claude-sonnet-4
- openai/gpt-4.1
- aws_bedrock/us.anthropic.claude-sonnet-4-20250514-v1:0Or as named aliases:
client:
haiku: aws_bedrock/us.anthropic.claude-haiku-4-5-20251001-v1:0
sonnet: anthropic/claude-sonnet-4
chatgpt: openai/gpt-5.2With aliases, you can select a client by name in the interactive menu
or pass the alias directly via
btw_client(client = "alias"). In non-interactive contexts,
the first client is used automatically (#153).
btw_agent_tool() allows you to create specialized
custom subagents from btw.md style markdown files. Agent
files are automatically discovered from .btw/agent-*.md
(project and user directories) and .claude/agents/ (for
Claude Code compatibility), and are registered as callable tools in
btw_tools(). Custom agents can specify their own system
prompts, icons, models, and available tools (#149).
btw_task() runs pre-formatted LLM tasks defined in
markdown files with YAML frontmatter. Task files support template
variable interpolation via {{ variable }} syntax, optional
client and tool configuration, and all four execution modes
("app", "console", "client",
"tool"). Task files can also specify title,
icon, description, and name
fields in their YAML frontmatter to customize the tool definition when
used in "tool" mode (#169).
btw_tool_agent_subagent() enables hierarchical agent
workflows by allowing an orchestrating LLM to delegate tasks to
subagents. Each subagent runs in its own isolated chat session with
restricted tool access and maintains conversation state that can be
resumed via session_id. This allows you to delegate tasks
to smaller cheaper models or reduce context bloat in the main
conversation (#149).
btw_tool_files_edit() makes targeted, validated
line-based edits to files using replace,
insert_after, and replace_range actions. Edits
are anchored to content hashes, so stale edits are rejected if the file
has changed. To support this, btw_tool_files_read() now
annotates each line with a short hash
(e.g. 2:f1a| return("world")) when called as a tool
(#167).
btw_tool_files_replace() finds and replaces exact
string occurrences in a file. By default it requires the string to
appear exactly once to prevent unintended changes; set
replace_all = TRUE to replace all occurrences
(#167).
btw_tool_pkg_load_all() runs
pkgload::load_all() in an isolated subprocess to verify
package code loads correctly and trigger recompilation of compiled code.
Useful for quick validation during development without running full
tests or affecting the current R session (#156).
btw_tool_skill() adds support for Agent Skills. Skills are modular,
on-demand capabilities that provide specialized instructions, bundled
scripts, reference docs, and asset templates to the LLM. Skills are
discovered automatically from the btw package, attached R packages with
inst/skills/ directories, user-level skills, and
project-level skills in .btw/skills/ or
.agents/skills/. When the skill tool is included in the
chat client, available skills are listed in the system prompt. Use
btw_skill_install_github() or
btw_skill_install_package() to install skills from external
sources, and btw_task_create_skill() to interactively
create new skills (#145).
btw_app() no longer errors with “argument is of
length zero” when run outside of an IDE (thanks @HenrikBengtsson, #168).
btw_app() no longer errors when provider built-in
tools (e.g. claude_tool_web_search()) are registered with a
btw client. Built-in tools now appear in the app sidebar under a
“Built-in” group (#175).
btw_tool_files_read() now correctly handles UTF-8
files containing CJK (Chinese, Japanese, Korean) characters. Previously,
the text-file detection could truncate a read buffer mid-way through a
multi-byte character, causing the file to be rejected as binary (thanks
@bianchenhao,
#170).
btw_tool_files_read() now correctly reads valid
UTF-8 files containing non-ASCII characters (e.g., Cyrillic).
Previously, these files were incorrectly rejected on Windows with
non-English locales when Encoding() returned “unknown” even
though they were valid UTF-8 (thanks @RKonstantinR, #160).
btw_client() now supports reading
CLAUDE.md files as project context files.
CLAUDE.md files are searched after AGENTS.md
but before user-level btw.md. YAML frontmatter in
CLAUDE.md files is stripped but not used for configuration
(#146).
btw_app() now shows a rich diff view in the
btw_tool_files_write_text_file() tool, if the
{diffviewer} package is installed (#144).
btw() now correctly handles character matrices
(#139).
btw_app() now correctly displays input tokens with
ellmer v0.4.0. Previously, we were showing the total input tokens sent
across all API calls, rather than the current number of input tokens as
of the last API call. We now show the size of the input context window
(i.e. the number of input tokens that will be used for the conversation
history in the next API call). Note that token usage is dependent on the
provider and model used and is only an estimate.
New “pkg” tool group with package development tools:
btw_tool_pkg_document(), btw_tool_pkg_check(),
btw_tool_pkg_test() and
btw_tool_pkg_coverage() provide LLMs with the ability to
document, check, test, and check test coverage of R packages during
development (#133, #136).
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).
btw_app() now works correctly with
{ellmer} v0.4.0 (#121).
btw_app() now shows more precise cost estimates when
the cost is less than $0.10 (#121).