rho.coding supplies coding tools with explicit execution semantics: file operations, Bash with a typed cross-platform resolution, isolated R evaluation in mirai, and opt-in evaluation in a caller-supplied current-session environment.
Isolated R evaluation
library(rho.async)
library(rho.ai)
library(rho.agent)
library(rho.coding)
r_tool <- rho_tool_r()
result <- rho_execute_tool(
r_tool,
ToolCall(
id = "readme-r-1",
name = "r",
arguments = list(code = "sum((1:6)^2)")
),
context = NULL
) |>
rho_await(timeout = 10000)
data.frame(
value = result@details$value,
may_overlap = S7::S7_inherits(r_tool@overlap, ToolMayOverlap)
)
#> value may_overlap
#> 1 91 TRUEThe ordinary R tool is isolated and may overlap with another call. A RhoCurrentSessionREvaluator instead receives an explicit environment and requires exclusive scheduling. RhoRExpression is also a RhoOperation, and the chosen evaluator is recorded in a RhoREvaluationBinding. A remote NNG evaluator therefore adds evaluator methods rather than another agent execution path. Bash follows the same discipline: on Windows it resolves a real Bash implementation rather than translating model-generated Bash into another shell language, and on Unix it reports a typed unavailable value when Bash is absent.
Session replay
The coding host may persist the agent journal as locked JSONL without making a path part of the agent contract. Versioned semantic records form the storage schema; package names, S7 class names, and reflected properties are not stored. Explicit adapters translate between those records and the current R classes. The project documentation records the schema evolution rules.
path <- tempfile(fileext = ".jsonl")
journal <- rho_jsonl_session_journal(path)
writer <- rho_agent(
rho_faux_provider(),
rho_model("faux", "faux"),
journal = journal
)
run <- rho_prompt(writer, "remember this turn") |>
rho_await(timeout = 10000)
reader <- rho_agent(
rho_faux_provider(),
rho_model("faux", "faux"),
journal = rho_jsonl_session_journal(path)
)
reader <- rho_sync_session(reader) |>
rho_await(timeout = 10000)
snapshot <- rho_session_snapshot(reader@journal) |>
rho_await(timeout = 10000)
data.frame(
committed_entries = snapshot@position,
restored_messages = length(rho_state_messages(reader))
)
#> committed_entries restored_messages
#> 1 2 2
unlink(c(path, paste0(path, ".lock")))The native format is Rho JSONL, not Pi session JSONL. Pi import or export can be added as another codec once session identity and branch lineage are exercised by Rho consumers.
See the rho.coding reference and its worker substrate, rho.compute.