generateText, streamText, or any other AI SDK function. The wrappers intercept every call transparently — no changes to your prompts, model configuration, or tool definitions required.
What gets captured
Mortem records the following for each agent run:- LLM calls — model ID, input messages, parameters, output text, and streamed content
- Tool invocations — tool name, input arguments, and output values
- Token counts — reported by the model provider where available
- Cost estimates — calculated from token usage and recorded on each
llm_callevent
Prerequisites
Install the SDK and create an agent in the dashboard before continuing. You needMORTEM_API_KEY and MORTEM_AGENT_ID set in your environment.
Integration
1
Initialize the Mortem client
Create a
Mortem instance at the top of your agent module. Pass your API key, agent ID, and the environment your bot runs on.verifyToken is only needed during your first deployment. Once the dashboard shows the agent as verified, remove MORTEM_VERIFY_TOKEN from your environment and code.2
Wrap your model and tools
Call Both wrappers are idempotent — wrapping the same model or tools object twice has no effect.
mortem.wrapLanguageModel and mortem.wrapTools before starting the session. Both wrappers mutate the object in place and return the same reference, so you can pass them directly to generateText.3
Start a session and run the agent
Create a session with
mortem.startSession, then execute your agent logic inside session.run. The session.run callback keeps Mortem’s async trace context active so all child LLM and tool events are associated with this trace.Complete example
The following is the full integration pattern in a single file:Streaming
mortem.wrapLanguageModel captures streaming responses too. When you use streamText instead of generateText, the wrapper taps the underlying doStream method and accumulates content deltas as they arrive. The llm_call event is completed with the full assembled content when the stream closes.
No extra configuration is needed — the same tracedModel works for both generateText and streamText.
Why session.run matters
session.run establishes an async context that child events — LLM calls, tool invocations — attach to. Without it, a top-level trace is created but the child events from inside generateText have no session to bind to and are silently dropped.