invoke() or agent execution. Nested prompt, parser, and intermediate runnable callbacks are skipped unless you opt into them with includeNestedRuns: true.
Installation
Quick Start
Configuration
| Option | Type | Required | Description |
|---|---|---|---|
apiKey | string | Yes | Vendor API key |
deploymentId | string | Yes | Deployment short ID (dep_...) |
privateKey | string | Yes | PEM Ed25519 private key |
apiUrl | string | No | API base URL |
deriveJobId | function | No | Custom job ID logic |
deriveMetadata | function | No | Custom receipt metadata |
deriveResolution | function | No | Custom resolution logic |
fetchImpl | function | No | Custom fetch implementation |
onReceiptSigned | function | No | Signed receipt callback with exact hashed payload |
onError | function | No | Error callback |
How It Works
The handler listens for these LangChain events:handleChainEnd— defaults to"success"resolutionhandleChainError— defaults to"failed"resolutionhandleAgentEnd— defaults to"success"resolution
deriveResolution, it overrides those defaults.
All derive hooks receive the LangChain output plus a context object with the
callback event, default resolution, run IDs, tags, optional inputs, and error
details when available.
Each receipt includes:
- A job ID for correlation across systems
- Default metadata including framework source, callback event, and execution hints
- A context hash derived from the chain output
- The exact normalized payload and hash used for
context_hashviaonReceiptSigned - An Ed25519 signature
lc-. If
you want to align receipts with your own internal jobs, provide deriveJobId.
Custom Resolution Logic
Override the default resolution inference:deriveResolution receives both the chain or agent output and a context object.
On handleChainError, the handler does not have output payload data, so the
default "failed" resolution is used unless your hook explicitly returns
something else.
Your hook should always return one of "success", "partial", or "failed".
If you also need receipt correlation with your own systems, use deriveJobId
to attach a vendor-controlled job identifier instead of the autogenerated lc-*
value.
If you need extra structured fields such as ticket IDs, workflow names, or
trace references, use deriveMetadata.
Derived metadata is merged on top of the default integration metadata. By
default, LangChain receipts include:
source: "langchain"eventrunIdandparentRunIdwhen availabletagswhen present- boolean hints such as
hasInputs,hasError, andhasAction
onReceiptSigned:
Hook Context
Each derive hook receives this context shape:runId for vendor-side correlation, event for branching on callback type,
and deriveMetadata for secondary identifiers that should travel with the
receipt without replacing your primary job ID.
Idempotency and Duplicate Suppression
The autogeneratedlc-* job IDs are fine for demos, but they are not
idempotent across retries. In production, prefer deriveJobId with a stable
identifier such as:
context.runIdwhen it represents the same logical job across retries- a request or ticket ID passed through chain inputs
- your own workflow execution ID from the application boundary
deriveMetadata, not in the
primary job_id.
LangChain can emit multiple callbacks for one user-visible workflow. The
VaultGraph handler submits only for the top-level LangChain run by default, so
an outer invoke() produces one receipt unless you opt into nested callbacks.
If you intentionally want one receipt per callback, set
includeNestedRuns: true and encode that explicitly in deriveJobId, for
example by including context.event.
Error Handling
The handler never crashes your agent. Submission errors are caught silently. Use theonError callback to log them: