SDK Reference
Lantern provides official SDKs for TypeScript and Python. The SDKs give you type-safe access to agent creation, durable steps, LLM calls, and streaming -- all with built-in retry logic and error handling.
TypeScript SDK
Installation
npm install @lantern/sdkCreating an agent
import { agent, step } from "@lantern/sdk";
export default agent({
name: "my-agent",
model: "auto",
async run({ input, ctx }) {
// Durable step -- survives crashes
const data = await step("fetch-data", async () => {
return ctx.tools.web.search(input.query);
});
// LLM call with capability routing
const summary = await step("summarize", async () => {
return ctx.llm.complete({
messages: [{ role: "user", content: `Summarize: ${data}` }],
capability: "reasoning-small",
});
});
return { summary };
},
});Durable steps
Steps are the core primitive. Each step is journaled, idempotent, and resumable:
// Simple step
const result = await step("step-name", async () => {
return someExpensiveOperation();
});
// Parallel fan-out
const results = await step.map("search", queries, async (query) => {
return ctx.tools.web.search(query);
});
// Conditional step
const approved = await step("check-approval", async () => {
return ctx.human.requestApproval({
message: "Send this email?",
timeout: "24h",
});
});Note: Steps must be deterministic in their scheduling. The same run with the same input must produce the same sequence of step names. Do not use random values or timestamps in step names.
LLM calls
// Text completion
const text = await ctx.llm.complete({
messages: [{ role: "user", content: "Explain quantum computing" }],
capability: "reasoning-large",
});
// Structured JSON output
const data = await ctx.llm.json({
prompt: "Extract entities from this text: ...",
schema: {
type: "object",
properties: {
people: { type: "array", items: { type: "string" } },
places: { type: "array", items: { type: "string" } },
},
},
capability: "reasoning-small",
});
// Streaming
const stream = await ctx.llm.stream({
messages: [{ role: "user", content: "Write a poem" }],
capability: "reasoning-small",
});
for await (const token of stream) {
process.stdout.write(token);
}Tool usage
// Connectors are available as typed tools
const emails = await ctx.tools.gmail.search({
query: "from:boss@company.com is:unread",
});
const issue = await ctx.tools.github.createIssue({
repo: "org/repo",
title: "Bug report",
body: "Details...",
});
// Web tools
const results = await ctx.tools.web.search("lantern ai platform");
const page = await ctx.tools.web.scrape("https://example.com");Human-in-the-loop
// Request approval before a sensitive action
const approved = await ctx.human.requestApproval({
message: "About to send email to 500 users. Proceed?",
timeout: "1h", // auto-reject if no response
channel: "slack", // where to send the approval request
});
if (!approved) {
return { status: "cancelled", reason: "Human rejected" };
}Client usage
import { LanternClient } from "@lantern/sdk";
const client = new LanternClient({
apiKey: process.env.LANTERN_API_KEY,
baseUrl: "https://api.lantern.run", // optional, defaults to this
});
// Create a run
const run = await client.agents.run("research-agent", {
input: { topic: "quantum computing" },
});
// Stream events
for await (const event of run.stream()) {
if (event.type === "token") {
process.stdout.write(event.content);
} else if (event.type === "step.complete") {
console.log(`Step ${event.step} completed in ${event.duration_ms}ms`);
}
}
// Get final result
const result = await run.result();Python SDK
Status: The Python SDK covers the full management surface (agents, runs, sessions, connectors, budgets, evals, experiments, marketplace, MCP, receipts, feedback, rehearsals) at parity with the TypeScript SDK. The agent runtime context (
AgentContext, durable step(), and ctx.llm) is not yet implemented -- those raiseNotImplementedError. The package is installed from the repository; it is not yet published to PyPI.Installation
# Install from the repository (not yet on PyPI)
pip install ./packages/sdk-pythonCreating an agent
from lantern import agent, step
@agent(name="my-agent", model="auto")
async def my_agent(input, ctx):
# Durable step
data = await step("fetch-data", lambda: ctx.tools.web.search(input["query"]))
# LLM call
summary = await step("summarize", lambda: ctx.llm.complete(
messages=[{"role": "user", "content": f"Summarize: {data}"}],
capability="reasoning-small",
))
return {"summary": summary}Client usage
from lantern import LanternClient
client = LanternClient(api_key="lnt_your_key")
# Create and stream a run
run = client.agents.run("research-agent", input={"topic": "quantum computing"})
for event in run.stream():
if event.type == "token":
print(event.content, end="", flush=True)
elif event.type == "step.complete":
print(f"\nStep {event.step} completed in {event.duration_ms}ms")
# Get the final result
result = run.result()
print(result)Async support
import asyncio
from lantern import AsyncLanternClient
async def main():
client = AsyncLanternClient(api_key="lnt_your_key")
run = await client.agents.run("research-agent", input={"topic": "AI safety"})
async for event in run.stream():
if event.type == "token":
print(event.content, end="", flush=True)
asyncio.run(main())Tip: Both SDKs handle retries, streaming reconnection, and error handling automatically. You do not need to implement retry logic -- use the built-in
@lantern/retry (TS) or the SDK's built-in retry behavior.Configuration
Both SDKs can be configured via environment variables:
LANTERN_API_KEY=lnt_your_key # Required
LANTERN_BASE_URL=https://api.lantern.run # Optional, for self-hosted
LANTERN_TIMEOUT=30000 # Request timeout in ms (default: 30s)
LANTERN_MAX_RETRIES=3 # Max retries on failure (default: 3)Error handling
// TypeScript
import { LanternError, RateLimitError } from "@lantern/sdk";
try {
const run = await client.agents.run("my-agent", { input: {} });
} catch (error) {
if (error instanceof RateLimitError) {
console.log(`Rate limited. Retry after ${error.retryAfter}s`);
} else if (error instanceof LanternError) {
console.log(`API error: ${error.code} - ${error.message}`);
}
}# Python
from lantern.errors import LanternError, RateLimitError
try:
run = client.agents.run("my-agent", input={})
except RateLimitError as e:
print(f"Rate limited. Retry after {e.retry_after}s")
except LanternError as e:
print(f"API error: {e.code} - {e.message}")