codeagent is an R-native coding agent: it wraps any
ellmer chat with a full agent harness (tools, permissions,
compaction, hooks, skills) and drives it from the R console, a terminal
REPL, or a Shiny app. This vignette walks from a first query to
configuration and sandboxing.
All code chunks below require a configured model endpoint and are therefore not evaluated when the vignette is built.
How it works
codeagent_client(chat) builds the harness once:
- injects tools (built mode="bypass") + system prompt
- register_midloop_compaction() -> chat$on_tool_result
- .install_permission_gate() -> chat$on_tool_request (sole authority)
One user turn = agent_loop(input, client, iteration)
iteration > max_turns? ---- yes ---> stop "max_turns"
| no
SessionStart hook (first turn)
inject system-reminder into the USER message (preserves prompt cache)
budget check ---- over ---> stop "budget_exceeded"
TURN-BOUNDARY compaction (if tokens >= window - margin)
UserMessage hook
|
v
chat$chat(input) -- ellmer runs the multi-round tool loop in-process --+
| per tool round: |
| on_tool_request -> PERMISSION GATE -> allow / deny / ask |
| tool executes |
| on_tool_result -> MID-LOOP compaction + PostToolUse hook |
+-- loops until the model stops requesting tools -------------------->+
|
v
final assistant turn
finish_reason == "length"? -> append truncation note
AssistantMessage hook
verify_fn? -- fail --> re-enter chat$chat(re-prompt) once
save_session()
Stop hook "completed" -> return {response, session_id, stop_reason}
Installation
# Install from GitHub (pak handles all dependencies including Rapp)
pak::pak(c("tidyverse/ellmer", "kaipingyang/codeagent"))Configuration (recommended:
~/.codeagent/settings.json)
The recommended way to configure codeagent is a user-level settings file. Create it with:
codeagent::use_codeagent_settings() # creates ~/.codeagent/settings.json from templateEdit the file to add your endpoint and credentials:
{
"model": "main",
"provider": "openai_compatible",
"env": {
"CODEAGENT_BASE_URL": "https://YOUR-WORKSPACE.cloud.databricks.net/serving-endpoints",
"CODEAGENT_MODEL": "your-main-endpoint",
"CODEAGENT_HEAVY_MODEL": "your-heavy-endpoint",
"CODEAGENT_FAST_MODEL": "your-fast-endpoint",
"CODEAGENT_API_KEY": "your-token"
},
"permissions": {
"defaultMode": "default"
}
}Note:
CODEAGENT_API_KEYin theenvblock is loaded at startup, so you do not need to set it separately in.Renviron.
Alternative: ~/.Renviron
Set the minimum required variables and restart R:
CODEAGENT_BASE_URL=https://YOUR-WORKSPACE.cloud.databricks.net/serving-endpoints
CODEAGENT_MODEL=your-main-endpoint
CODEAGENT_API_KEY=your-tokenAll CODEAGENT_* variables in ~/.Renviron
are loaded automatically, even when running under --vanilla
(e.g. via the CLI).
CLI
Installing codeagent does not automatically put a
codeagent command on your PATH. Run this once after
installation:
codeagent::install_codeagent_cli()Then use from any terminal:
1. Build a client
A codeagent client wraps an ellmer::Chat.
With settings.json configured, the simplest form is:
library(codeagent)
# Auto-build from ~/.codeagent/settings.json
client <- codeagent_client()Or provide an explicit ellmer::Chat:
chat <- ellmer::chat_openai_compatible(
base_url = Sys.getenv("CODEAGENT_BASE_URL"),
model = Sys.getenv("CODEAGENT_MODEL"),
credentials = function() Sys.getenv("CODEAGENT_API_KEY")
)
client <- codeagent_client(chat)codeagent_client() injects the tool set (Bash, Read,
Write, Edit, Glob, Grep, LS, plus btw tool groups) and
builds the system prompt. The permission_mode controls how
tool calls are gated – see section 5.
2. One-shot queries
codeagent(client, "List the .R files in R/ and summarise what each does")The agent plans, calls tools, and returns a final answer. History accumulates on the client, so follow-up calls keep context.
3. Interactive REPL
From R:
codeagent_console(client)Or from a terminal (after running
install_codeagent_cli() once):
codeagent # interactive REPL (default permission mode)
codeagent -y # bypass mode (skip all permission prompts)
codeagent "query" # one-shot queryInside the REPL, slash commands include /model,
/compact, /clear, /rewind,
/sessions, and /budget; /name
invokes a skill.
4. Shiny app
codeagent_app(client, theme = "default")The app streams output, renders tool cards, and provides session management and a searchable skill panel.
5. Permissions
Permission mode decides whether a tool call is allowed, denied, or requires confirmation:
| Mode | Behaviour |
|---|---|
default |
reads auto-allow; writes and shell require confirmation |
plan |
read-only; all mutating tools denied |
accept_edits |
file edits auto-allow; Bash still asks |
bypass |
everything allowed |
dont_ask |
mutating tools auto-denied (CI) |
bubble |
sub-agent mode; decisions bubble to the parent |
Fine-grained rules match on tool arguments – for example, allow only a specific command:
client <- codeagent_client(
chat,
permission_mode = "default",
rules = list(PermissionRule("Bash", "allow", rule_content = "R CMD build *"))
)6. Configuration with settings.json
Scaffold a settings file:
use_codeagent_settings(scope = "user")It mirrors the schema of command-line coding agents (model tiers, an
env block, permissions, hooks, MCP servers, sandbox, effort
level). Precedence, low to high: package defaults, then
~/.codeagent/settings.json, then
.codeagent/settings.json, then environment variables.
Keep API keys in .Renviron (as
CODEAGENT_API_KEY), never in
settings.json.
7. Sandboxed R execution
The RunR tool executes R code behind the permission
gate. Enable sandboxing to run each call in an isolated
callr subprocess with a scrubbed environment (API keys are
not visible), no .Renviron reload, and a wall-clock
timeout:
Sandboxing is opt-in because spawning a subprocess has a small cost. Turn it on when executing less-trusted code; leave it off for fast, local, trusted use.
8. Multi-agent teams
Run independent tasks in parallel, capped to the container’s CPU quota:
# Fixed fan-out
team_run(c("review R/a.R", "review R/b.R"))
# Work-stealing over a shared board (balances uneven task sizes)
team_coordinate(c("task 1", "task 2", "task 3", "task 4"))Where to go next
-
?codeagent_client– all client options (tool groups, verification, MCP). -
?codeagent_app– Shiny app themes and panels. - README – feature overview and provider reference.