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 listings below show what each one exposes.
The 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. For the raw endpoints see the API reference.
TypeScript SDK
Section titled “TypeScript SDK”Installation
Section titled “Installation”# in your checkout of github.com/dshakes/lantern( cd packages/sdk-ts && npm install && npm run build )# in your project: a file path, not the registrynpm install /path/to/lantern/packages/sdk-tsAfter that, import { LanternClient } from "@lantern/sdk" resolves to the built dist/. Rebuild after pulling changes.
Client setup
Section titled “Client 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});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
Section titled “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 runfor 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 resultconst finished = await client.runs.get(run.id);console.log(finished.status, finished.output);Interactive sessions
Section titled “Interactive sessions”// Create a sessionconst session = await client.sessions.create({ agent: "my-agent" });
// Stream a message turnfor 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("\nDone:", chunk.usage);}
// Non-streaming send: returns immediately; the reply arrives on sessions.events()await client.sessions.sendMessage(session.id, { content: "Follow-up question",});
// Cleanupawait client.sessions.delete(session.id);All namespaces
Section titled “All namespaces”client.agents // create, get, list, deleteclient.runs // create, get, list, cancel, events, signal, forecastclient.sessions // create, get, list, sendMessage, streamMessage, events, stop, delete, closeclient.connectors // list, get, execute, test, uninstallclient.budgets // upsert, get, list, deleteclient.evalSuites // upsert, list, get, deleteclient.evalRuns // record, listclient.evalBaselines // set, getclient.experiments // create, list, get, recordOutcome, concludeclient.marketplace // list, get, publish, fork, star, unstarclient.mcp // listServers, getServer, attach, listAttachments, detachclient.receipts // issue, verifyclient.feedback // submit, listForRun, summaryForAgentclient.rehearsals // pullclient.runtime // schedule, list, get, terminate, exec, execStream, pause, resume, fork, listFiles, readFile, writeFileError handling
Section titled “Error 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 streamtry { 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
Section titled “Python SDK”Installation
Section titled “Installation”# from the root of your checkoutpip install ./packages/sdk-python# optional: LangChain deepagents sandbox backend (lantern.integrations.deepagents_sandbox)pip install "./packages/sdk-python[deepagents]"Client setup
Section titled “Client 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())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
Section titled “Creating a run”run = await client.runs.create(agent="research-agent", input={"topic": "AI safety"})print(run.id, run.status) # queuedAll namespaces
Section titled “All namespaces”client.agents # create, get, list, deleteclient.runs # create, get, list, cancel, events, signal, forecastclient.sessions # create, get, list, send_message, stream_events, stop, delete, closeclient.connectors # list, get, execute, list_actionsclient.budgets # upsert, get, delete, list_allclient.evals # upsert_suite, list_suites, get_suite, delete_suite, record_run, list_runs, set_baseline, get_baselineclient.experiments # create, list, get, record_outcome, concludeclient.marketplace # list, get, publish, fork, star, unstarclient.mcp # list_servers, get_server, attach, detach, list_attachmentsclient.receipts # issue, verifyclient.feedback # submit, list_for_run, summary_for_agentclient.rehearsals # pullclient.runtime # schedule, list, get, terminate, exec, exec_stream, pause, resume, fork, list_files, read_file, write_fileExample: list agents
Section titled “Example: list agents”resp = await client.agents.list()for agent in resp.agents: print(agent.name, agent.current_version_id)Agent runtime (TypeScript)
Section titled “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 }; },});Use capability names like auto, reasoning-large, chat-small, vision-large. Do not 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
Section titled “Parallel fan-out”const results = await step.map("search", queries, async (query) => { return ctx.tools.web.search(query);});Human approval
Section titled “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.