pub enum Value {
Show 13 variants
String(String),
Int(i64),
Decimal(f64),
List(Vec<Value>),
Document(String),
AgentRef(AgentData),
Object(HashMap<String, Value>),
Bool(bool),
Unable(UnableRecord),
Union {
variant: String,
payload: Box<Value>,
},
FatalError {
message: String,
kind: ErrorKind,
code: ErrorCode,
user_message: String,
retry_after_ms: Option<u64>,
source: ErrorSource,
},
Json(Value),
Null,
}Variants§
String(String)
Int(i64)
Decimal(f64)
Fractional numeric value. Backed by f64 for now (master plan §D1
— “we do not need more digits right now”). The variant name decouples
the value-layer rename (Float → Decimal) from a future swap to
rust_decimal::Decimal, which is a non-breaking value-layer-only
change. JSON serialisation always emits a JSON number — there is
no envelope.
List(Vec<Value>)
Document(String)
AgentRef(AgentData)
Object(HashMap<String, Value>)
Bool(bool)
Unable(UnableRecord)
Structured Unable payload from a task declared T | Unable.
On-wire shape is the envelope { "unable": { ... } } — see
to_json / from_json below for the exact round-trip.
Union
Discriminated-union payload from a task whose declared return type
is A | B | ... | Unable (#226). variant is the canonical record
name (e.g. "Feature", "ClaimErr") and payload is the parsed
record with the kind discriminator stripped. The Unable arm is
still represented as Value::Unable — this variant only carries
non-Unable arms. The wire shape is {"kind": "<variant>", ...}.
FatalError
Failure value carrying full structured detail. Construct via
Value::fatal, Value::fatal_kind, or Value::fatal_code —
they fill code, user_message, etc. consistently. Existing
pattern matches like Value::FatalError { message, kind, .. }
continue to work; reach for the extra fields when surfacing
errors externally (engine events, OTel, DB).
Fields
code: ErrorCodeStable ErrorCode (e.g. ProviderRateLimit,
ScriptDepthExceeded). Defaults to ErrorCode::Other for
legacy paths that haven’t been migrated, and serializes via
the canonical AKRIBES-E-XXX wire form.
user_message: StringUser-facing single-paragraph summary + suggested action.
Defaults to ErrorCode::default_user_message when not
explicitly overridden.
retry_after_ms: Option<u64>When the upstream provider supplied a Retry-After (or
equivalent), the suggested wait in milliseconds. Skipped on
the wire when absent.
source: ErrorSourceWhere in the workflow the error originated (task/agent/ provider/model/tool_ref/script/line). Skipped on the wire when no fields are set.
Json(Value)
Opaque JSON payload. Emitted by stdlib builtins that accept or
return loosely-typed JSON (e.g. a future std.json_parse). The
engine does not introspect it; consumers (Studio, SDKs) render
it as collapsible pretty-printed JSON. Not produced by any M1
builtin — the variant ships now so every match site downstream
is exhaustive before M7/M8 land.
Null
Implementations§
Source§impl Value
impl Value
Sourcepub fn to_wire_json(&self) -> Value
pub fn to_wire_json(&self) -> Value
Project this Value to its canonical wire-format JSON shape.
Alias for Value::to_json — kept as a named entry point so
EngineEvent serialization sites that carry workflow output
values across the wire can call a method whose name says exactly
what it does. Both methods produce the same JSON; new code that
is specifically about wire-format projection should prefer this
one for readability at the call site.
Spec: docs/src/content/docs/reference/engine-events.mdx — the
wire format never exposes the internal tagged-Value form to
consumers. See Value::to_json for the per-variant projection
rules.
Sourcepub fn to_json(&self) -> Value
pub fn to_json(&self) -> Value
Convert to plain JSON without Rust enum tags.
The default serde serialization wraps every variant in its tag:
Value::String("hi") → {"String":"hi"}. This method produces
clean JSON: "hi", 42, [...], {...}, etc.
For Value::Unable, the output is the canonical envelope
{ "unable": { "reason": ..., "missing": [...], "category": ... } }
— the same shape the schema advertises and that providers return.
Object key order is NOT a guarantee of this method.
Value::Object is HashMap-backed, so iteration order is
indeterminate, and the resulting serde_json::Map’s order
further depends on whether serde_json was compiled with
preserve_order. Callers that need stable key ordering for
hashing / golden output / wire-compat should route through
akribes_core::stdlib::lookup("json_stringify") — issue #866 —
which canonically alpha-sorts every nested object via its
internal canonicalize pass.
Sourcepub fn from_json(v: &Value) -> Self
pub fn from_json(v: &Value) -> Self
Convert from plain JSON into a Value.
Does not auto-detect the Unable envelope — callers that want
to discriminate a T | Unable result should first consult
akribes_core::unable::is_unable_envelope and then construct
Value::Unable explicitly. This keeps from_json a pure
shape-preserving decoder and avoids surprising callers who
legitimately want an Object with an "unable" key.
Symmetrically, Value::Union is not auto-detected from the
{"kind": "<variant>", ...} wire shape because user records may
legitimately carry a kind field. A Value::Union { variant, payload } produced by Value::to_json round-trips back as a
Value::Object whose kind key survives in the data — the type
tag is lost. Callers that have the static return type available
should use Value::from_json_with_union_arms to reconstruct
the Value::Union tag deterministically (#1289).
Sourcepub fn from_json_with_union_arms(v: &Value, arm_names: &[&str]) -> Self
pub fn from_json_with_union_arms(v: &Value, arm_names: &[&str]) -> Self
Decode plain JSON into a Value, lifting variant-union payloads
when the wire shape {"kind": "<variant>", ...} matches one of
the declared arm_names. Symmetric inverse of Value::to_json
for Value::Union { variant, payload }.
Falls back to Value::from_json when:
- the value is not an object;
- the object has no
"kind"string field; kinddoes not name any ofarm_names.
Sourcepub fn fatal(detail: ErrorDetail) -> Self
pub fn fatal(detail: ErrorDetail) -> Self
Build a Value::FatalError from a fully-formed ErrorDetail.
Prefer Value::fatal_kind / Value::fatal_code for the common
quick-construction cases.
Sourcepub fn fatal_kind(kind: ErrorKind, message: impl Into<String>) -> Self
pub fn fatal_kind(kind: ErrorKind, message: impl Into<String>) -> Self
Quick-construct a fatal error from a kind + developer message.
Code and user_message are derived via ErrorDetail::from_kind.
Use this at sites that don’t yet have a specific ErrorCode;
reach for Value::fatal_code as soon as you do.
Sourcepub fn fatal_code(code: ErrorCode, message: impl Into<String>) -> Self
pub fn fatal_code(code: ErrorCode, message: impl Into<String>) -> Self
Quick-construct a fatal error from a specific ErrorCode.
Kind and user_message are derived from the code.
Sourcepub fn as_fatal_detail(&self) -> Option<ErrorDetail>
pub fn as_fatal_detail(&self) -> Option<ErrorDetail>
Build an ErrorDetail from a FatalError value, or None for
any other variant. Clones — use for cross-boundary handoff (engine
event emission, DB serialization).
Sourcepub fn fatal_with_code(
message: impl Into<String>,
kind: ErrorKind,
code: impl AsRef<str>,
) -> Self
👎Deprecated: use Value::fatal_code(ErrorCode::X, msg) instead
pub fn fatal_with_code( message: impl Into<String>, kind: ErrorKind, code: impl AsRef<str>, ) -> Self
use Value::fatal_code(ErrorCode::X, msg) instead
Back-compat shim for the legacy string-coded fatal_with_code
helper (#429). Internally normalises the string to an
ErrorCode via ErrorCode::from_wire; unrecognised codes
fall through to ErrorCode::Other.
Trait Implementations§
Source§impl<'de> Deserialize<'de> for Value
impl<'de> Deserialize<'de> for Value
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Source§impl From<Value> for WorkflowEndPayload
impl From<Value> for WorkflowEndPayload
Source§impl Hash for Value
Deterministic Hash for Value, used for task-cache keys.
impl Hash for Value
Deterministic Hash for Value, used for task-cache keys.
Notes:
Value::Decimal(f64-backed per §D1) is hashed throughnormalized_f64_bitsso-0.0/+0.0collide and every NaN payload collapses to a single canonical key. See issue #1012.Objectentries are sorted by key before hashing sinceHashMapiteration order is not stable across runs or insertions.