> ## Documentation Index
> Fetch the complete documentation index at: https://developers.telnyx.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Calling LLMs

> Bring your own LLM and your own loop — or your own framework. The SDK converts history to whatever format your stack expects.

The Agent SDK does not run a model and does not impose an agent framework. The loop
that does the thinking — the [harness](/docs/agent-sdk#bring-your-own-harness) — is
yours to choose; the SDK supplies the durable substrate —
[history](/docs/agent-sdk/message-history), [timers](/docs/agent-sdk/scheduled-tasks),
[state](/docs/agent-sdk/state) — and `this.messages` converts that history into the
format your LLM stack expects. There are two broad ways to wire a harness in.

## Roll your own loop

Your `process()` method **is** the agent loop: build the message list, make one call,
handle the reply. The [Telnyx API binding](/docs/edge-compute/telnyx-api) is a
pre-authenticated client — declare `[telnyx]` in `telnyx.toml` and inference is a
method call, no API key to manage. `this.messages.toOpenAI()` produces exactly the
payload it takes:

```ts theme={null}
async process(): Promise<void> {
  const history = await this.messages.toOpenAI();

  // An API error rejects → the task fails → the scheduler retries
  const res = await this.env.TELNYX.ai.openai.chat.createCompletion({
    model: "zai-org/GLM-5.2",
    messages: [{ role: "system", content: SYSTEM_PROMPT }, ...history],
  });
  await this.messages.add("assistant", res.choices[0].message.content);
}
```

Bringing a different provider? Any OpenAI-compatible endpoint works over `fetch` —
swap the URL, model, and a key held in a
[secret](/docs/edge-compute/configuration/secrets). The official `openai` and
`@anthropic-ai/sdk` clients work too, fed by `toOpenAI()` and `toAnthropic()`.

→ Full example: [Roll Your Own Agent](/docs/agent-sdk/examples/roll-your-own)

## Bring a framework

Any agent framework that runs on Node — LangGraph, LangChain, and friends — runs inside
`process()`, with the SDK as its durable memory. `toLangChain()` returns plain
`{ role, content }` messages, which LangGraph accepts as-is:

```ts theme={null}
const llm = new ChatOpenAI({
  model: "zai-org/GLM-5.2",
  apiKey: process.env.TELNYX_API_KEY,
  configuration: { baseURL: "https://api.telnyx.com/v2/ai/openai" },
});
const supportAgent = createReactAgent({ llm, tools: [lookupOrder] });

async process(): Promise<void> {
  const history = await this.messages.toLangChain();
  const out = await supportAgent.invoke({ messages: history });
  await this.messages.add("assistant", String(out.messages.at(-1)?.content ?? ""));
}
```

The framework owns the reasoning loop and tool calls; the actor owns durability,
retries, and follow-up timers.

→ Full example: [LangGraph Agent](/docs/agent-sdk/examples/langgraph)

## Where to make the call

Make LLM calls from a **queued or scheduled task**, not from the inbound method.
Inbound RPC runs under a 30-second budget; tasks run in the actor's alarm handler with
a budget on the order of minutes, and a thrown error triggers [retry with
backoff](/docs/agent-sdk/scheduled-tasks) instead of a lost webhook. See
[How Agents Run](/docs/agent-sdk/concepts/how-agents-run).
