Writes a self-contained, hash-sealed archive of a run: the study
agent_manifest() (manifest.json), the transcript (transcript.csv), the
event / call / tool / state views, the per-call provenance (calls.jsonl,
the LLMR audit log copied verbatim when one was kept), any artifacts, a
drafted methods note (README-methods.md), and a hashes.sha256 manifest
over every file written. The archive is the supplementary material a paper
can ship: it carries the declared specification and the calls' provenance, not
just the prose.
Usage
archive_agent_study(
run,
path,
include_messages = TRUE,
redact = NULL,
formats = c("csv", "jsonl", "rds"),
overwrite = FALSE
)Arguments
- run
An object accepted by
as_agent_run()(an Agent, a conversation or preset result, a pipeline, an experiment, or anagent_run).- path
Directory to write into; created (recursively) if absent.
- include_messages
If
TRUE(default), write the transcript and the free-text columns of the tool and state tables. IfFALSE, those tables are still written but their free-text columns are blanked, keeping only structure, hashes, and metadata; the records incalls.jsonllikewise omit the request body and reply text (each record keeps its precomputedrequest_hash, so the join invariant holds).- redact
Optional redaction applied to the free-text columns of the written transcript, tool, and state tables (
text,content,arguments,result,response_text) and to the reply text of the records incalls.jsonl– never to hashes, and never to a request body, which is the call's identity (omit request bodies withinclude_messages = FALSE). Either afunction(text) -> text, or a character vector of regular expressions, each of which is replaced by"[REDACTED]". Redaction is applied to the on-disk copy after hashing, so the join invariant holds.- formats
Which optional formats to write, any of
"csv"(the tabular views),"jsonl"(events and calls; always written), and"rds"(the privacy-filtered, data-only run snapshot asrun.rds). Defaults to all three.- overwrite
If
FALSE(default), refuse a non-emptypath. Set toTRUEto replace archive files in an existing directory.
Value
Invisibly, an object of class agent_archive: a list with path,
files (relative paths written), manifest_hash, and n_calls. Print
lists what was written and confirms the seal.
Details
The archive is privacy-preserving at its serialization boundary: run.rds
is a data-only snapshot of the same projected levels written to the text
formats. Live agents, callers, tool functions, model configurations, and
configuration secrets are never serialized into the archive. Message
omission and redaction apply to this snapshot as well as the text files.
Hashes are identity, not outcome. The request_hash in calls.jsonl is
computed over the original request, so a call read back from the archive
still matches the same call issued live. Redaction therefore never touches a
hash or a request body, and when an LLMR audit log is present it is copied
byte-for-byte rather than reserialized – unless a privacy lever is engaged:
with include_messages = FALSE each copied record's request body and reply
text are removed (its precomputed request_hash is kept, so the join
survives), and with redact the copied records' reply text is scrubbed.
Examples
if (FALSE) { # \dontrun{
a <- agent("Aria", LLMR::llm_config("groq", "openai/gpt-oss-20b"))
a$chat("Hello")
archive_agent_study(a, tempfile("study_"))
} # }