Trace and span APIs
Own a trace lifecycle and record custom provider attempts.
Scoped and manual traces
public func withTrace<Result>(
_ name: String, version: Int = 1,
input: (any Encodable & Sendable)? = nil,
operation: (LedgeTrace) async throws -> Result
) async throws -> Result
public func startTrace(
_ name: String, version: Int = 1,
input: (any Encodable & Sendable)? = nil
) async throws -> LedgeTracewithTrace finishes, fails, or cancels automatically and preserves the closure's
original return value or thrown error. It supports caller-isolated operations.
startTrace validates setup and returns a nonoptional actor with public id: UUID.
LedgeTrace.record(nativeSession, agent:) creates a native adapter. Manual owners
call finish(), fail(error), or cancel(), all async and nonthrowing. Repeated
finalization is a no-op. Finishing early marks unfinished spans interrupted; empty
traces are not uploaded. See workflow examples.
Custom provider spans
public func startSpan(
agent: LedgeAgent,
modelInput: LedgeJSONValue? = nil,
model: LedgeJSONValue? = nil,
recording: LedgeRecording = .init()
) async throws -> LedgeSpanThis advanced method belongs to LedgeTrace and is called once per actual provider
attempt. It throws LedgeTraceError.alreadyFinished if the owner is closed.
Persistence or capture failures emit diagnostics rather than throwing.
A LedgeSpan is Sendable and exposes its id: UUID.
public func complete(
modelInput: LedgeJSONValue? = nil,
modelOutput: LedgeJSONValue? = nil,
providerCapture: LedgeJSONValue? = nil,
status: LedgeStatus = .success,
error: LedgeError? = nil
) asyncCompletion preserves the initial model input when no replacement native input is
provided. Record success, failure, or cancellation at the provider boundary. Interrupted
work has no observed completion timestamp. Completed spans are immutable; duplicate
completion cannot alter their output. Application annotations come from recording:
at start.