Skip to contents

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 an agent_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. If FALSE, those tables are still written but their free-text columns are blanked, keeping only structure, hashes, and metadata; the records in calls.jsonl likewise omit the request body and reply text (each record keeps its precomputed request_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 in calls.jsonl – never to hashes, and never to a request body, which is the call's identity (omit request bodies with include_messages = FALSE). Either a function(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 as run.rds). Defaults to all three.

overwrite

If FALSE (default), refuse a non-empty path. Set to TRUE to 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_"))
} # }