mesedi
v0.7.0
Published
Mesedi SDK — guardians for autonomous AI agents. Detect failures, halt runaways, escalate first occurrence.
Maintainers
Readme
Mesedi TypeScript SDK
Status: v0.4.0. Live on npm.
The TypeScript companion to sdk-python/. Feature parity for the v1
surface (configure(), wrap(), tool(), async event shipper,
fail-open posture), built on Node 18+ native fetch,
AsyncLocalStorage, and node:zlib for opt-in gzip compression of
request bodies above 1 KB. Zero runtime dependencies. Compresses
or not transparently; small calls ship uncompressed as before.
Install
npm install mesediAPI
import { configure, wrap, tool, flush } from "mesedi";
configure({
apiKey: "mesedi_sk_...",
baseUrl: "http://localhost:8080",
});
// Define a tool. Observed when called from inside a wrap()'d function.
const searchWeb = tool({ name: "search_web" }, async (q: string) => {
return ["result1", "result2"];
});
// Wrap an agent function. Records start/complete/crash automatically.
const runAgent = wrap(async (query: string) => {
const results = await searchWeb(query);
return `found ${results.length} results`;
});
await runAgent("pickleball");
// At end-of-script, flush any in-flight events:
await flush();What lands at the backend
For each wrap()-decorated call:
- On entry:
POST /executions(status=started, sdk_language=typescript, sdk_version=0.4.0). - On normal return:
PATCH /executions/{id}(status=completed, duration_ms, ended_at). - On thrown error:
PATCH /executions/{id}(status=crashed, crash_signature). The original error is then re-thrown with its original stack.
For each tool()-decorated call (from inside a wrap()):
POST /eventswith event_type=tool_call, sequence number from the surrounding execution's context, payload includes tool_name + sanitized args + status + result_summary (or exception fields).
All HTTP is async via a single in-process queue + a setInterval
drainer. Network failures during observation NEVER throw back into the
wrapped agent. The SDK is fail-open: a Mesedi outage degrades to
invisibility, not to broken production code.
Framework integrations
Adapter modules under mesedi/integrations/* translate each framework's
native callback or hook surface into Mesedi telemetry. They're optional;
importing mesedi itself never requires any framework to be installed.
Currently shipping: LangGraph, OpenAI Agents SDK, and Vercel AI SDK. Each peer dependency is opt-in.
LangGraph
import { configure, wrap } from "mesedi";
import { instrumentGraph } from "mesedi/integrations/langgraph";
configure({ apiKey: process.env.MESEDI_API_KEY! });
export const runMyGraph = wrap(async (question: string) => {
const graph = buildGraph();
instrumentGraph(graph);
const result = await graph.invoke({ input: question });
return result.output;
});instrumentGraph attaches Mesedi telemetry to each node in the graph
and emits llm_call and tool_call events labeled with the node name,
so the dashboard timeline shows the graph's flow alongside per-step
detail.
OpenAI Agents SDK
import { configure, wrap } from "mesedi";
import { instrumentAgent } from "mesedi/integrations/openai_agents";
configure({ apiKey: process.env.MESEDI_API_KEY! });
export const runMyAgent = wrap(async (question: string) => {
const agent = buildAgent();
instrumentAgent(agent);
return agent.run(question);
});instrumentAgent subscribes to the OpenAI Agents SDK's lifecycle hooks
and emits llm_call + tool_call events with the same wire format as
the LangGraph and Vercel AI SDK adapters, so detectors see no
difference.
Vercel AI SDK
If your agent uses Vercel's ai package (generateText, multi-step
ReAct with tools + maxSteps), you don't have to wrap every tool by
hand. wrapGenerateText is a one-line higher-order function that
returns a drop-in replacement for generateText with Mesedi telemetry
side effects.
import { configure, wrap, flush } from "mesedi";
import { wrapGenerateText } from "mesedi/integrations/vercel_ai";
import { generateText } from "ai";
import { openai } from "@ai-sdk/openai";
configure({ apiKey: process.env.MESEDI_API_KEY! });
const generateTextM = wrapGenerateText(generateText);
export const runAgent = wrap(
{ name: "support-triage" },
async (question: string) => {
const result = await generateTextM({
model: openai("gpt-4o"),
prompt: question,
tools: { lookup, search },
maxSteps: 5,
});
return result.text;
},
);Per invocation, the wrapper emits:
- One
llm_callevent per step (Vercel's multi-step ReAct surfaces intermediate reasoning + final answer onresult.steps). Model id, user message, system prompt, token usage, response text, all captured in the standard Mesedi wire format. - One
tool_callevent per tool invocation in each step. Pairsresult.toolCalls[i]toresult.toolResultsbytoolCallId, detects failure mode (missing result ORresult.errorfield) and recordsstatus=failedwithexception_type/exception_message.
Detectors (drift, identical/similar-call loops, tool-failures,
cost-velocity, prompt-injection) see the same wire format as a
hand-written mesedi instrumentation produces.
ai is declared as an optional peer dependency. Installing
mesedi doesn't require it. If your project already has ai
installed for generateText, the integration just works.
Only generateText is wrapped today. streamText and generateObject
are not currently supported; use hand-instrumentation with
emitLLMCall / tool() for those code paths.
Releases
This SDK is published to npm via OIDC Trusted Publishing from the
release-sdk-typescript.yml GitHub Actions workflow, with no long-lived
NPM_TOKEN secret. Every release carries an npm provenance attestation
linking it to a specific commit in mesedi-ai/mesedi.
To cut a new release, bump version in package.json, commit, then:
git tag -a sdk-typescript-v0.X.Y -m "Release sdk-typescript v0.X.Y"
git push origin sdk-typescript-v0.X.YThe workflow installs, builds, and publishes with --provenance.
