Anthropic
Claude models with streaming, function calling, thinking and prompt caching through AnthropicLLMService.
Overview
AnthropicLLMService runs Claude models through the Anthropic Messages API. It streams text,
calls functions, supports thinking and prompt caching, and accepts any client with the same
beta.messages.create() shape.
AnthropicLLMService: the LLM service, withAnthropicLLMSettingsfor runtime-updatable settings andAnthropicThinkingConfigfor thinking.
Upstream page
Pipecat's documentation for the same service.
Source
packages/anthropic/src/llm.ts and anthropic_adapter.ts.
Anthropic docs
The Messages API, models, thinking and prompt caching.
Installation
bun add @pipedog/anthropicimport { AnthropicLLMService, AnthropicThinkingConfig } from "@pipedog/anthropic/llm";The package depends on the official @anthropic-ai/sdk, which is installed with it.
Prerequisites
- An Anthropic account and an API key from the Anthropic Console.
- Pass the key as
apiKey. The examples read it fromANTHROPIC_API_KEY.
AnthropicLLMService
Configuration
Prop
Type
apiKey is required even when you pass your own client, which doesn't use it.
Settings
Runtime-updatable settings, passed as settings: new AnthropicLLMService.Settings({...}). Any
setting you leave out keeps the default below. null means the field is not sent, so Anthropic
uses its own default.
| Setting | Type | Default | Description |
|---|---|---|---|
model | string | "claude-sonnet-4-6" | Claude model id. |
systemInstruction | string | null | null | System prompt. |
maxTokens | number | null | 4096 | Maximum tokens to generate. |
temperature | number | null | null | Sampling temperature. Sent through extra_body. |
topK | number | null | null | Top-k sampling. Sent through extra_body. |
topP | number | null | null | Top-p sampling. Sent through extra_body. |
enablePromptCaching | boolean | false | Add cache-control markers to the system prompt and recent messages. |
systemPromptCacheTtl | "5m" | "1h" | null | null (Anthropic: 5 minutes) | Lifetime of the system prompt's cache entry when caching is on. |
thinking | AnthropicThinkingConfig | null | null | Thinking configuration. See below. |
effort | "low" | "medium" | "high" | "xhigh" | "max" | null | null | Sent as output_config.effort. null uses the model's default. |
useProviderThinkingDefault | boolean | false | Run at Anthropic's default when neither thinking nor effort is set. |
extra | Record<string, unknown> | {} | Extra request parameters, merged into the request. |
frequencyPenalty, presencePenalty and seed exist on the base LLMSettings and default to
null; the Anthropic API does not use them.
AnthropicThinkingConfig
Prop
Type
When the model thinks, the service emits LLMThoughtStartFrame, LLMThoughtTextFrame and
LLMThoughtEndFrame. Claude 4.7 and later return empty thinking text unless display is
"summarized".
Usage
import { AnthropicLLMService, AnthropicThinkingConfig } from "@pipedog/anthropic/llm";
import { LLMUpdateSettingsFrame } from "@pipedog/core/frames/frames";
const llm = new AnthropicLLMService({
apiKey: process.env.ANTHROPIC_API_KEY ?? "",
settings: new AnthropicLLMService.Settings({
model: "claude-sonnet-4-6",
systemInstruction: "You are a helpful voice assistant. Keep answers short.",
maxTokens: 1024,
enablePromptCaching: true,
}),
});
llm.addEventHandler("on_completion_timeout", async () => {
console.log("LLM completion timed out");
});Adaptive thinking with readable thinking text:
const thinkingLlm = new AnthropicLLMService({
apiKey: process.env.ANTHROPIC_API_KEY ?? "",
settings: new AnthropicLLMService.Settings({
model: "claude-opus-4-7",
maxTokens: 16384,
thinking: new AnthropicThinkingConfig({ type: "adaptive", display: "summarized" }),
}),
});Change settings mid-call with an LLMUpdateSettingsFrame:
// Queue it on the worker, or push it from a processor upstream of the service.
const update = new LLMUpdateSettingsFrame({
delta: new AnthropicLLMService.Settings({ temperature: 0.3, maxTokens: 512 }),
});Event handlers
Inherited from LLMService:
| Event | Description |
|---|---|
on_completion_timeout | A completion request timed out. |
on_function_calls_started | Function calls arrived and are about to run. |
on_function_calls_cancelled | One or more running function calls were cancelled. |
Notes
- Consumes
LLMContextFrameand emitsLLMFullResponseStartFrame,LLMTextFrames andLLMFullResponseEndFrame. AnLLMEnablePromptCachingFrameturns prompt caching on or off. - When neither
thinkingnoreffortis set, the service sends the lowest thinking setting Anthropic documents for the model, for the fastest responses:thinking: { type: "disabled" }on most Claude 4 and 5 models,"between_tools"on Claude Sonnet 5.5, andeffort: "low"on Claude Opus 5.5 and Fable models. It logs what it sent. A Claude model not in that list runs at Anthropic's default, with a warning. SetuseProviderThinkingDefault: trueto skip this. - Bedrock and Vertex model ids (
us.anthropic.claude-sonnet-5-...,claude-sonnet-5@...) and dated snapshots are matched to their model's entry. - Models from the 4.6 generation on reject assistant prefill. For those, the service adds a trailing user message when the context ends with an assistant message.
runInferenceaccepts aresponseSchema. It is sent asoutput_config.formatand needs a 4.5 model or later.- With
retryOnTimeout: true, the first attempt is limited toretryTimeoutSecs(5 by default). If it times out, the request is retried once with no timeout. - The service logs a warning when Claude stops for a reason other than a normal end, such as
max_tokensor a refusal. The text that arrived is still passed on. - Token usage metrics include cache creation, cache read and reasoning tokens.
Runtime notes
| Runtime | Works | What it needs |
|---|---|---|
| Bun | ✅ yes | Nothing. |
| Node.js | ✅ yes | Nothing. |
| Deno | ✅ yes | Nothing. |
| Cloudflare Workers | ✅ yes | Nothing. |
Generated from pipecat.runtimes and pipecat.compat in packages/anthropic/package.json: ✅ means the compat smoke test passes on that runtime.
@anthropic-ai/sdkis fetch-based and runs on Bun, Node, Deno and Cloudflare Workers.clienttakes any object with abeta.messages.create(params, { signal })method, such asAnthropicBedrockorAnthropicVertexfrom Anthropic's Bedrock and Vertex SDKs (not dependencies of this package).- The Python SDK's
NOT_GIVENhas no JS counterpart: sampling settings andthinkingusenullfor "not sent". An explicitnullsampling value is left out of the request, where upstream sends JSONnull. - The JS SDK has no
extra_bodyoption. pipedog mergesextra_bodyinto the request JSON itself, as the Python SDK does. - The JS SDK has no
RequestTooLargeError; a 413 is recognized by its status. - Not ported: the deprecated
AnthropicLLMService.InputParamsand themodel/paramsconstructor arguments. Usesettings.
pipedog is an unofficial community TypeScript port of Pipecat. It is not affiliated with or endorsed by Daily or the Pipecat project.
Portions adapted from the Pipecat documentation, Copyright (c) 2024–2025 Daily, BSD-2-Clause (see apps/docs/LICENSE-pipecat-docs).