LedgeKitDocs
Advanced
Developer documentation

Record another model provider

Place one invocation immediately around each actual provider request.

Use startInvocation and complete when an existing provider integration cannot use LedgeLanguageModelSession. Your adapter supplies native request/response data as JSON and preserves the provider result for the application.

import LedgeKit

func recordProviderRequest(
    run: LedgeTraceHandle?,
    input: LedgeJSONValue,
    call: () async throws -> LedgeJSONValue
) async throws -> LedgeJSONValue {
    let invocation = await run?.startInvocation(
        agent: .init(name: "summarizer", version: 1), input: input
    )
    do {
        let output = try await call()
        await invocation?.complete(input: input, output: output)
        return output
    } catch is CancellationError {
        await invocation?.complete(input: input, output: nil, status: .cancelled)
        throw CancellationError()
    } catch {
        await invocation?.complete(
            input: input, output: nil,
            status: .failure, error: LedgeError(error)
        )
        throw error
    }
}

The caller starts and finalizes the run. call must wrap one real provider request, with input/output matching that request. Supply model metadata at start and native capture at completion when the provider exposes them. The minimal JSON callback above illustrates the boundary; adapt it to return your provider's original response type in a production adapter.

Preserve the model outcome

Finish the invocation before application parsing or validation. A later application error may fail the workflow, but should not rewrite the model result. Complete each invocation once; subsequent completion attempts cannot overwrite it.

startInvocation can return nil for an invalid definition, finished run, or unknown relationship ID. Treat that as recording unavailable, or validate your definitions explicitly when testing instrumentation.

Use relationships for parent, retry, and handoff IDs.

On this page