SDK Reference
Three SDKs: TypeScript (@lantern/sdk), Python (lantern-sdk, imported as lantern) and Go (github.com/dshakes/lantern/packages/sdk-go). They cover agents, runs, sessions, connectors, budgets, evals, experiments, marketplace, MCP, receipts, feedback, rehearsals and sandbox VMs. The TypeScript client has the most surface; the tables below list what each one really exposes.
In plain termsThe SDKs wrap the REST API in typed methods, so you call
client.runs.create(...) instead of writing HTTP. Use them to trigger agents from your app, wire runs into your backend, or script bulk operations.TypeScript SDK
Installation
npm install @lantern/sdkClient setup
import { LanternClient } from "@lantern/sdk";
const client = new LanternClient({
apiKey: process.env.LANTERN_API_KEY, // hlx_live_...
baseUrl: process.env.LANTERN_API_URL, // e.g. http://localhost:8080
});Environment variables. With no constructor options the SDK reads
LANTERN_API_KEY and LANTERN_API_URL. If LANTERN_API_URL is unset, the base URL defaults to https://api.lantern.run, so set it for a self-hosted control plane. (LANTERN_RUNTIME=true is a different switch: the platform sets it inside a running agent to enable the production sidecar.)Creating and streaming a run
import type { Run } from "@lantern/sdk";
// Create a run (create() returns an event stream instead when you pass stream: true)
const run = (await client.runs.create({
agent: "research-agent",
input: { topic: "quantum computing" },
})) as Run;
console.log(run.id, run.status); // queued
// Stream events for the run
for await (const event of client.runs.events(run.id)) {
console.log(event.kind, event.stepId, event.data);
// kinds include step_started, step_completed, step_failed, tool_call, tool_result, llm_delta, log, approval, end
}
// Fetch final result
const finished = await client.runs.get(run.id);
console.log(finished.status, finished.output);Interactive sessions
// Create a session
const session = await client.sessions.create({ agent: "my-agent" });
// Stream a message turn
for await (const chunk of client.sessions.streamMessage(session.id, {
content: "What is the capital of France?",
})) {
// chunk.type is "delta" | "completed"; a server-side message_error throws MessageStreamError
if (chunk.type === "delta") process.stdout.write(chunk.delta);
if (chunk.type === "completed") console.log("
Done:", chunk.usage);
}
// Non-streaming send: returns immediately; the reply arrives on sessions.events()
await client.sessions.sendMessage(session.id, {
content: "Follow-up question",
});
// Cleanup
await client.sessions.delete(session.id);All namespaces
client.agents // create, get, list, delete
client.runs // create, get, list, cancel, events, signal, forecast
client.sessions // create, get, list, sendMessage, streamMessage, events, stop, delete, close
client.connectors // list, get, execute, test, uninstall
client.budgets // upsert, get, list, delete
client.evalSuites // upsert, list, get, delete
client.evalRuns // record, list
client.evalBaselines // set, get
client.experiments // create, list, get, recordOutcome, conclude
client.marketplace // list, get, publish, fork, star, unstar
client.mcp // listServers, getServer, attach, listAttachments, detach
client.receipts // issue, verify
client.feedback // submit, listForRun, summaryForAgent
client.rehearsals // pull
client.runtime // schedule, list, get, terminate, exec, execStream, pause, resume, fork, listFiles, readFile, writeFileError handling
import { LanternApiError, MessageStreamError } from "@lantern/sdk";
try {
await client.runs.create({ agent: "my-agent", input: {} });
} catch (err) {
if (err instanceof LanternApiError) {
console.error(err.status, err.message);
}
}
// Errors during a session stream
try {
for await (const chunk of client.sessions.streamMessage(id, { content: "hi" })) {
// ...
}
} catch (err) {
if (err instanceof MessageStreamError) {
console.error("stream error:", err.message);
}
}Retries are built in. The TypeScript client retries HTTP 429, 503 and network errors up to 3 attempts with full-jitter backoff (500 ms base, 4 s cap). It never retries other 4xx or 5xx. There is no separate
@lantern/retry package.Sandbox VMs live under client.runtime in TypeScript and Python; Go has ScheduleVM, PauseVM, ResumeVM, ForkVM, ListFiles, ReadFile and WriteFile. See Sandbox Lifecycle.
Python SDK
Status. The Python management client is usable today. The in-agent runtime context (
ctx.llm, ctx.tools, ctx.mem and the rest) raises NotImplementedError; write agent logic in TypeScript for now. Install from the repo; this page does not claim a PyPI release.Installation
pip install ./packages/sdk-pythonClient setup
from lantern import LanternClient
client = LanternClient(
api_key="hlx_live_your_key", # or LANTERN_API_KEY env var
base_url="http://localhost:8080", # or LANTERN_API_URL env var
)
# Request methods are coroutines: call from async code, or asyncio.run(main())Async.
LanternClient is built on httpx.AsyncClient: every request method is async def; runs.events, sessions.stream_events and runtime.exec_stream return async iterators (async for). Use async with LanternClient(...) as client or call await client.close().Creating a run
run = await client.runs.create(agent="research-agent", input={"topic": "AI safety"})
print(run.id, run.status) # queuedAll namespaces
client.agents # create, get, list, delete
client.runs # create, get, list, cancel, events, signal, forecast
client.sessions # create, get, list, send_message, stream_events, stop, delete, close
client.connectors # list, get, execute, list_actions
client.budgets # upsert, get, delete, list_all
client.evals # upsert_suite, list_suites, get_suite, delete_suite, record_run, list_runs, set_baseline, get_baseline
client.experiments # create, list, get, record_outcome, conclude
client.marketplace # list, get, publish, fork, star, unstar
client.mcp # list_servers, get_server, attach, detach, list_attachments
client.receipts # issue, verify
client.feedback # submit, list_for_run, summary_for_agent
client.rehearsals # pull
client.runtime # schedule, list, get, terminate, exec, exec_stream, pause, resume, fork, list_files, read_file, write_fileExample: list agents
resp = await client.agents.list()
for agent in resp.agents:
print(agent.name, agent.current_version_id)Agent runtime (TypeScript)
Inside an agent bundle, ctx gives you durable steps, LLM calls, tools, memory and connectors. Each step is journaled, so a crashed run resumes instead of restarting:
import { agent, step } from "@lantern/sdk";
export default agent<{ query: string }>({
name: "my-agent",
model: "auto",
async run({ input, ctx }) {
// Durable step — journaled, idempotent, resumable on crash
const data = await step("fetch-data", async () => {
return ctx.tools.web.search(input.query);
});
// LLM call — addressed by capability; the model router picks the vendor model
const summary = await step("summarize", async () => {
return ctx.llm.complete({
messages: [{ role: "user", content: `Summarize: ${data}` }],
capability: "reasoning-small",
});
});
return { summary };
},
});Model capability strings. Use capability names like
auto, reasoning-large, chat-small, vision-large. Don't hardcode a vendor model. The model router maps the capability to a concrete model at call time. See Models for the full list.Parallel fan-out
const results = await step.map("search", queries, async (query) => {
return ctx.tools.web.search(query);
});Human approval
// Blocks until a human grants or denies.
await ctx.approval.request({
reason: "Send this email to 500 users?",
expiresAt: "2026-12-01T00:00:00Z",
});
// Reaching this line means it was granted. Denial or timeout throws LanternError.