Module: Riffer::Agent::Serializer
Overview
Riffer::Agent::Serializer turns a resolved agent into a self-contained, provider-neutral data dict and back into a runnable agent. A pure module (sibling to Riffer::Agent::Run), reached most often through the Riffer::Agent#to_h / Riffer::Agent.from_h delegators.
The dict carries only data — no Procs, no class references, no tool runtime. The same dict serves two rehydration targets:
-
In-process (a monolith persisting agent definitions): pass a
tool_resolverthat looks tool descriptors up in a local registry and returns the real, body-bearing classes. They run on the default runtime. -
Distributed (a receiver holding only the Riffer gem): the default resolver synthesizes body-less tool shells; inject a remote
Riffer::Tools::Runtimeto forward each call back to the origin.dict = Riffer::Agent::Serializer.to_h(agent: agent) rebuilt = Riffer::Agent::Serializer.from_h(dict, context: “acme”)
What does not transfer
Guardrails and the skills subsystem (backend/adapter/catalog) are not serialized; a rebuilt agent enforces no guardrails and renders no skills catalog (the skill_activate tool, if present, crosses as an ordinary tool). Secrets must not be placed in provider_options/model_options: both ride on the wire as plain data.
Defined Under Namespace
Classes: VersionError
Constant Summary collapse
- SCHEMA_VERSION =
The wire format version. Bumped only on an incompatible change to the dict shape;
from_hrefuses any other version. Seefrom_hfor the dispatch seam that carries back-compat decoders. 1- DEFAULT_TOOL_RESOLVER =
The default
tool_resolver: synthesizes a body-less tool shell from a descriptor. Its#callraises — route shells through a remote runtime. ->(descriptor) { build_tool_shell(descriptor) }
Instance Method Summary collapse
-
#from_h(hash, context: nil, tool_resolver: DEFAULT_TOOL_RESOLVER, tool_runtime: nil) ⇒ Object
Reconstructs a runnable agent from a wire dict.
-
#from_json(json, context: nil, tool_resolver: DEFAULT_TOOL_RESOLVER, tool_runtime: nil) ⇒ Object
Reconstructs a runnable agent from a JSON string produced by
to_json. -
#to_h(agent:) ⇒ Object
Snapshots a resolved agent into a self-contained wire dict.
-
#to_json(agent:) ⇒ Object
Snapshots a resolved agent to a JSON string.
Instance Method Details
#from_h(hash, context: nil, tool_resolver: DEFAULT_TOOL_RESOLVER, tool_runtime: nil) ⇒ Object
Reconstructs a runnable agent from a wire dict.
- hash
-
a Symbol-keyed wire dict (parse JSON with symbolize_names: true).
- context
-
the rebuilt agent’s runtime context — the same value you’d pass
to +Agent.new(context:)+. It is *not* used to re-resolve serialized
config (the dict is already resolved); it is threaded into tool dispatch
and read by tools/runtimes at call time (e.g. a remote runtime keying off
<tt>context[:tenant]</tt>). Defaults to an empty context.
- tool_resolver
-
maps a tool descriptor to a Riffer::Tool class. Defaults
to DEFAULT_TOOL_RESOLVER (body-less shells). Pass a registry lookup to
rebuild real, in-process tools.
- tool_runtime
-
an optional Riffer::Tools::Runtime to inject (e.g. a
remote runtime for shells). When omitted, the agent uses the configured
default (+Riffer.config.tool_runtime+).
Raises Riffer::Agent::Serializer::VersionError on an unsupported schema_version, and Riffer::ArgumentError on a malformed dict.
– : (Hash[Symbol, untyped], ?context: Hash[Symbol, untyped]?, ?tool_resolver: ^(Hash[Symbol, untyped]) -> singleton(Riffer::Tool), ?tool_runtime: (singleton(Riffer::Tools::Runtime) | Riffer::Tools::Runtime | Proc)?) -> Riffer::Agent
94 95 96 97 98 99 100 101 102 103 |
# File 'lib/riffer/agent/serializer.rb', line 94 def from_h(hash, context: nil, tool_resolver: DEFAULT_TOOL_RESOLVER, tool_runtime: nil) # Version -> decoder dispatch. Adding a +when 2+ arm (a backwards-compatible # decoder) is how a future breaking change keeps older dicts readable. case hash[:schema_version] when SCHEMA_VERSION decode_v1(hash, context: context, tool_resolver: tool_resolver, tool_runtime: tool_runtime) else raise VersionError, "Unsupported schema_version: #{hash[:schema_version].inspect} (this Riffer supports #{SCHEMA_VERSION})" end end |
#from_json(json, context: nil, tool_resolver: DEFAULT_TOOL_RESOLVER, tool_runtime: nil) ⇒ Object
Reconstructs a runnable agent from a JSON string produced by to_json. Handles the JSON parse (with symbol keys) so callers don’t have to. See from_h for the arguments.
– : (String, ?context: Hash[Symbol, untyped]?, ?tool_resolver: ^(Hash[Symbol, untyped]) -> singleton(Riffer::Tool), ?tool_runtime: (singleton(Riffer::Tools::Runtime) | Riffer::Tools::Runtime | Proc)?) -> Riffer::Agent
120 121 122 |
# File 'lib/riffer/agent/serializer.rb', line 120 def from_json(json, context: nil, tool_resolver: DEFAULT_TOOL_RESOLVER, tool_runtime: nil) from_h(JSON.parse(json, symbolize_names: true), context: context, tool_resolver: tool_resolver, tool_runtime: tool_runtime) end |
#to_h(agent:) ⇒ Object
Snapshots a resolved agent into a self-contained wire dict.
Reads the agent’s resolved instance state — Proc-based settings have already been evaluated against the agent’s own context, so the dict carries plain strings/data, never Procs. Tools are emitted as {name, description, parameters_schema, timeout} descriptors (the resolved agent.tools, including MCP tools and skill_activate).
- agent
-
a resolved Riffer::Agent instance.
– : (agent: Riffer::Agent) -> Hash[Symbol, untyped]
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/riffer/agent/serializer.rb', line 58 def to_h(agent:) config = agent.config { schema_version: SCHEMA_VERSION, riffer_version: Riffer::VERSION, identifier: config.identifier, model: "#{agent.provider_name}/#{agent.model_name}", instructions: agent.&.content, model_options: config., provider_options: config., max_steps: encode_max_steps(config.max_steps), structured_output: config.structured_output&.to_json_schema(strict: false), tools: agent.tools.map { |tool_class| tool_descriptor(tool_class) } } end |
#to_json(agent:) ⇒ Object
Snapshots a resolved agent to a JSON string. Convenience over JSON.generate(to_h(agent:)).
– : (agent: Riffer::Agent) -> String
110 111 112 |
# File 'lib/riffer/agent/serializer.rb', line 110 def to_json(agent:) JSON.generate(to_h(agent: agent)) end |