LangChain JS (ChatAnthropic)
ChatAnthropic from @langchain/anthropic, on plugboard's Messages API. For the OpenAI-shaped client, see LangChain JS.
Connect
anthropicApiUrl is the plugboard origin, without /v1:
ts
export function chatModel(model: string, overrides: Record<string, unknown> = {}) {
return new ChatAnthropic({
model,
anthropicApiUrl: plugboardURL,
anthropicApiKey: plugboardKey,
maxTokens: 1024,
maxRetries: 0,
...overrides,
})
}Tool calls
ts
const llm = chatModel(model).bindTools([getWeather])
const first = await llm.invoke([new HumanMessage(PROMPT)])
const call = first.tool_calls?.[0]
if (!call) throw new Error("turn 1 had no tool call")
const second = await llm.invoke([new HumanMessage(PROMPT), first, new ToolMessage({ tool_call_id: call.id!, content: JSON.stringify(weatherResult) })])Streaming
ts
for await (const chunk of await chatModel(model).stream(PROMPT)) {
text += typeof chunk.content === "string" ? chunk.content : chunk.content.map((part) => ("text" in part ? part.text : "")).join("")
// The stop reason arrives on the message_delta chunk, in additional_kwargs (not response_metadata).
if (typeof chunk.additional_kwargs.stop_reason === "string") finish = finishReason(chunk.additional_kwargs.stop_reason)
if (chunk.usage_metadata) usage = chunk.usage_metadata
}The stop reason of a streamed answer is on the last chunk, in additional_kwargs.stop_reason.
Structured output
ts
const output = await chatModel(model).withStructuredOutput(Meal, { name: "record_meal" }).invoke(PROMPT)Limits
ChatAnthropichas no model-list call.GET /v1/modelswith your key works.- Errors carry
error.typeand noerror.code.