@langchain/anthropic 1.4.0-dev-1775763803878 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +30 -0
- package/README.md +85 -0
- package/dist/chat_models.cjs +63 -37
- package/dist/chat_models.cjs.map +1 -1
- package/dist/chat_models.d.cts +24 -13
- package/dist/chat_models.d.cts.map +1 -1
- package/dist/chat_models.d.ts +24 -13
- package/dist/chat_models.d.ts.map +1 -1
- package/dist/chat_models.js +64 -38
- package/dist/chat_models.js.map +1 -1
- package/dist/profiles.cjs +53 -53
- package/dist/profiles.cjs.map +1 -1
- package/dist/profiles.js +53 -53
- package/dist/profiles.js.map +1 -1
- package/dist/utils/message_inputs.cjs +0 -51
- package/dist/utils/message_inputs.cjs.map +1 -1
- package/dist/utils/message_inputs.js +1 -51
- package/dist/utils/message_inputs.js.map +1 -1
- package/dist/utils/params.cjs +42 -0
- package/dist/utils/params.cjs.map +1 -0
- package/dist/utils/params.js +40 -0
- package/dist/utils/params.js.map +1 -0
- package/dist/utils/stream_events.cjs +70 -85
- package/dist/utils/stream_events.cjs.map +1 -1
- package/dist/utils/stream_events.js +70 -85
- package/dist/utils/stream_events.js.map +1 -1
- package/dist/utils/tools.cjs +3 -2
- package/dist/utils/tools.cjs.map +1 -1
- package/dist/utils/tools.js +2 -1
- package/dist/utils/tools.js.map +1 -1
- package/package.json +6 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,35 @@
|
|
|
1
1
|
# @langchain/anthropic
|
|
2
2
|
|
|
3
|
+
## 1.4.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#10777](https://github.com/langchain-ai/langchainjs/pull/10777) [`0cfcfc6`](https://github.com/langchain-ai/langchainjs/commit/0cfcfc66897d8fafeb7e7ed90b7299eace9a7c37) Thanks [@jonaslalin](https://github.com/jonaslalin)! - feat(anthropic): support strict tool calling for custom tools
|
|
8
|
+
|
|
9
|
+
## 1.3.29
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- [#10735](https://github.com/langchain-ai/langchainjs/pull/10735) [`1a2a08a`](https://github.com/langchain-ai/langchainjs/commit/1a2a08a33b7d99ec7348678116cc5d074db137bb) Thanks [@chenzimin](https://github.com/chenzimin)! - feat(anthropic): add automatic prompt caching via top-level cache_control
|
|
14
|
+
|
|
15
|
+
## 1.3.28
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- [#10776](https://github.com/langchain-ai/langchainjs/pull/10776) [`20a9abe`](https://github.com/langchain-ai/langchainjs/commit/20a9abea23ffacf4ae8dc9a7aeec217143bbdeb6) Thanks [@hntrl](https://github.com/hntrl)! - fix(deps): remediate uuid vulnerability by removing direct uuid usage
|
|
20
|
+
|
|
21
|
+
- Updated dependencies [[`20a9abe`](https://github.com/langchain-ai/langchainjs/commit/20a9abea23ffacf4ae8dc9a7aeec217143bbdeb6)]:
|
|
22
|
+
- @langchain/core@1.1.42
|
|
23
|
+
|
|
24
|
+
## 1.3.27
|
|
25
|
+
|
|
26
|
+
### Patch Changes
|
|
27
|
+
|
|
28
|
+
- [#10726](https://github.com/langchain-ai/langchainjs/pull/10726) [`ad153c1`](https://github.com/langchain-ai/langchainjs/commit/ad153c185b6cf813d4b7695740d9a4453d2cb63f) Thanks [@hntrl](https://github.com/hntrl)! - feat(anthropic): add Claude Opus 4.7 compatibility updates
|
|
29
|
+
|
|
30
|
+
- Updated dependencies [[`589f29c`](https://github.com/langchain-ai/langchainjs/commit/589f29ce844eb252c2d5e6b0f8d26de37763a0d7), [`2e9e696`](https://github.com/langchain-ai/langchainjs/commit/2e9e6969e248a53ede0659a41d0ac8dbaf291ab4)]:
|
|
31
|
+
- @langchain/core@1.1.41
|
|
32
|
+
|
|
3
33
|
## 1.3.26
|
|
4
34
|
|
|
5
35
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -75,6 +75,91 @@ const response = await model.stream({
|
|
|
75
75
|
});
|
|
76
76
|
```
|
|
77
77
|
|
|
78
|
+
### Strict Tool Use
|
|
79
|
+
|
|
80
|
+
Anthropic supports [strict tool use](https://platform.claude.com/docs/en/agents-and-tools/tool-use/strict-tool-use), which uses grammar-constrained sampling to guarantee that Claude's tool inputs match your schema (no missing required fields, no wrong types). Enable it on a per-call, per-binding, or per-tool basis.
|
|
81
|
+
|
|
82
|
+
**Per-call** with `bindTools` (applies to every tool in the binding):
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
import { ChatAnthropic } from "@langchain/anthropic";
|
|
86
|
+
import { tool } from "langchain";
|
|
87
|
+
import { z } from "zod";
|
|
88
|
+
|
|
89
|
+
const getWeather = tool(async ({ location }) => `Weather in ${location}`, {
|
|
90
|
+
name: "get_weather",
|
|
91
|
+
description: "Get the current weather in a given location",
|
|
92
|
+
schema: z.object({ location: z.string() }),
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
const model = new ChatAnthropic({ model: "claude-opus-4-7" });
|
|
96
|
+
|
|
97
|
+
const response = await model
|
|
98
|
+
.bindTools([getWeather], { strict: true })
|
|
99
|
+
.invoke("What's the weather in San Francisco?");
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
**Default for a tool-bound model** with `withConfig` (applies to every subsequent call on the bound model):
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
const strictModelWithTools = model
|
|
106
|
+
.bindTools([getWeather])
|
|
107
|
+
.withConfig({ strict: true });
|
|
108
|
+
|
|
109
|
+
const response = await strictModelWithTools.invoke(
|
|
110
|
+
"What's the weather in San Francisco?"
|
|
111
|
+
);
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
**Per-tool** with `extras.strict` for mixed strict/non-strict tool sets:
|
|
115
|
+
|
|
116
|
+
```typescript
|
|
117
|
+
const lookupCustomer = tool(async ({ id }) => `...`, {
|
|
118
|
+
name: "lookup_customer",
|
|
119
|
+
description: "Look up a customer by id",
|
|
120
|
+
schema: z.object({ id: z.string() }),
|
|
121
|
+
// Strict on this critical tool only.
|
|
122
|
+
extras: { strict: true },
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
const searchDocs = tool(async ({ query }) => `...`, {
|
|
126
|
+
name: "search_docs",
|
|
127
|
+
description: "Free-form documentation search",
|
|
128
|
+
schema: z.object({ query: z.string() }),
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
const response = await model
|
|
132
|
+
.bindTools([lookupCustomer, searchDocs])
|
|
133
|
+
.invoke("Find customer 12345 and any onboarding docs");
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
**With `withStructuredOutput`** to guarantee schema-conforming output:
|
|
137
|
+
|
|
138
|
+
```typescript
|
|
139
|
+
const Weather = z.object({
|
|
140
|
+
location: z.string(),
|
|
141
|
+
temperature_celsius: z.number(),
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
const structured = model.withStructuredOutput(Weather, {
|
|
145
|
+
method: "functionCalling",
|
|
146
|
+
strict: true,
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
const result = await structured.invoke("What's the weather in San Francisco?");
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Precedence when multiple sources are set:
|
|
153
|
+
|
|
154
|
+
1. Per-call `strict` (e.g. `bindTools(..., { strict })`, `withConfig({ strict })`, or `withStructuredOutput(..., { strict })`)
|
|
155
|
+
2. Per-tool `strict` (e.g. `extras.strict`, `function.strict` on OpenAI-shaped tools, or `strict` on raw Anthropic-shaped tools)
|
|
156
|
+
|
|
157
|
+
In other words, per-tool acts as a fallback default for tools that opt in; if the call already specifies `strict`, that value wins for every tool in the request.
|
|
158
|
+
|
|
159
|
+
> **Note on `withStructuredOutput` methods:** Anthropic's `strict` is a property of a tool definition, so it only applies when `method: "functionCalling"` (the default), where the structured output is produced by a strict tool call.
|
|
160
|
+
>
|
|
161
|
+
> The other method, `"jsonSchema"`, uses Anthropic's [native structured outputs](https://docs.claude.com/en/docs/build-with-claude/structured-outputs) and does not accept `strict`. Passing `strict` together with `"jsonSchema"` or `"jsonMode"` throws, to avoid silently dropping the option. If you want strict-validated output, stick with the default `functionCalling` method.
|
|
162
|
+
|
|
78
163
|
## Tools
|
|
79
164
|
|
|
80
165
|
This package provides LangChain-compatible wrappers for Anthropic's built-in tools. These tools can be bound to `ChatAnthropic` using `bindTools()` or any [`ReactAgent`](https://docs.langchain.com/oss/javascript/langchain/agents).
|
package/dist/chat_models.cjs
CHANGED
|
@@ -2,6 +2,7 @@ require("./_virtual/_rolldown/runtime.cjs");
|
|
|
2
2
|
const require_output_parsers = require("./output_parsers.cjs");
|
|
3
3
|
const require_tools = require("./utils/tools.cjs");
|
|
4
4
|
const require_message_inputs = require("./utils/message_inputs.cjs");
|
|
5
|
+
const require_params = require("./utils/params.cjs");
|
|
5
6
|
const require_message_outputs = require("./utils/message_outputs.cjs");
|
|
6
7
|
const require_errors = require("./utils/errors.cjs");
|
|
7
8
|
const require_profiles = require("./profiles.cjs");
|
|
@@ -20,6 +21,7 @@ let _langchain_core_utils_standard_schema = require("@langchain/core/utils/stand
|
|
|
20
21
|
let _langchain_core_language_models_structured_output = require("@langchain/core/language_models/structured_output");
|
|
21
22
|
//#region src/chat_models.ts
|
|
22
23
|
const MODEL_DEFAULT_MAX_OUTPUT_TOKENS = {
|
|
24
|
+
"claude-opus-4-7": 16384,
|
|
23
25
|
"claude-opus-4-6": 16384,
|
|
24
26
|
"claude-sonnet-4-6": 16384,
|
|
25
27
|
"claude-opus-4-5": 16384,
|
|
@@ -649,7 +651,7 @@ var ChatAnthropicMessages = class extends _langchain_core_language_models_chat_m
|
|
|
649
651
|
model: modelOrFields
|
|
650
652
|
} : modelOrFields ?? {};
|
|
651
653
|
super(fields ?? {});
|
|
652
|
-
this._addVersion("@langchain/anthropic", "1.4.0
|
|
654
|
+
this._addVersion("@langchain/anthropic", "1.4.0");
|
|
653
655
|
this.anthropicApiKey = fields?.apiKey ?? fields?.anthropicApiKey ?? (0, _langchain_core_utils_env.getEnvironmentVariable)("ANTHROPIC_API_KEY");
|
|
654
656
|
if (!this.anthropicApiKey && !fields?.createClient) throw new Error("Anthropic API key not found");
|
|
655
657
|
this.clientOptions = fields?.clientOptions ?? {};
|
|
@@ -689,31 +691,48 @@ var ChatAnthropicMessages = class extends _langchain_core_language_models_chat_m
|
|
|
689
691
|
* Formats LangChain StructuredTools to AnthropicTools.
|
|
690
692
|
*
|
|
691
693
|
* @param {ChatAnthropicCallOptions["tools"]} tools The tools to format
|
|
694
|
+
* @param fields Optional `strict` flag applied to every formatted custom tool.
|
|
692
695
|
* @returns {AnthropicTool[] | undefined} The formatted tools, or undefined if none are passed.
|
|
693
696
|
*/
|
|
694
|
-
formatStructuredToolToAnthropic(tools) {
|
|
697
|
+
formatStructuredToolToAnthropic(tools, fields) {
|
|
695
698
|
if (!tools) return;
|
|
696
699
|
return tools.map((tool) => {
|
|
697
700
|
if ((0, _langchain_core_utils_function_calling.isLangChainTool)(tool) && tool.extras?.providerToolDefinition) return tool.extras.providerToolDefinition;
|
|
698
701
|
if (isBuiltinTool(tool)) return tool;
|
|
699
|
-
if (isAnthropicTool(tool))
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
702
|
+
if (isAnthropicTool(tool)) {
|
|
703
|
+
if (fields?.strict !== void 0) return {
|
|
704
|
+
...tool,
|
|
705
|
+
strict: fields.strict
|
|
706
|
+
};
|
|
707
|
+
return tool;
|
|
708
|
+
}
|
|
709
|
+
if ((0, _langchain_core_language_models_base.isOpenAITool)(tool)) {
|
|
710
|
+
const functionStrict = "strict" in tool.function && typeof tool.function.strict === "boolean" ? tool.function.strict : void 0;
|
|
711
|
+
const strict = fields?.strict ?? functionStrict;
|
|
712
|
+
return {
|
|
713
|
+
name: tool.function.name,
|
|
714
|
+
description: tool.function.description,
|
|
715
|
+
input_schema: tool.function.parameters,
|
|
716
|
+
...strict !== void 0 ? { strict } : {}
|
|
717
|
+
};
|
|
718
|
+
}
|
|
719
|
+
if ((0, _langchain_core_utils_function_calling.isLangChainTool)(tool)) {
|
|
720
|
+
const { strict: extrasStrict, ...restExtras } = tool.extras ? require_tools.AnthropicToolExtrasSchema.parse(tool.extras) : {};
|
|
721
|
+
const strict = fields?.strict ?? extrasStrict;
|
|
722
|
+
return {
|
|
723
|
+
name: tool.name,
|
|
724
|
+
description: tool.description,
|
|
725
|
+
input_schema: (0, _langchain_core_utils_types.isInteropZodSchema)(tool.schema) ? (0, _langchain_core_utils_json_schema.toJsonSchema)(tool.schema) : tool.schema,
|
|
726
|
+
...restExtras,
|
|
727
|
+
...strict !== void 0 ? { strict } : {}
|
|
728
|
+
};
|
|
729
|
+
}
|
|
711
730
|
throw new Error(`Unknown tool type passed to ChatAnthropic: ${JSON.stringify(tool, null, 2)}`);
|
|
712
731
|
});
|
|
713
732
|
}
|
|
714
733
|
bindTools(tools, kwargs) {
|
|
715
734
|
return this.withConfig({
|
|
716
|
-
tools: this.formatStructuredToolToAnthropic(tools),
|
|
735
|
+
tools: this.formatStructuredToolToAnthropic(tools, { strict: kwargs?.strict }),
|
|
717
736
|
...kwargs
|
|
718
737
|
});
|
|
719
738
|
}
|
|
@@ -738,31 +757,38 @@ var ChatAnthropicMessages = class extends _langchain_core_language_models_chat_m
|
|
|
738
757
|
return Object.keys(base).length > 0 ? base : void 0;
|
|
739
758
|
})();
|
|
740
759
|
const compactionBetas = this.contextManagement?.edits?.some((e) => e.type === "compact_20260112") ? ["compact-2026-01-12"] : [];
|
|
760
|
+
const taskBudgetBetas = require_params.getTaskBudgetBetas(this.model, mergedOutputConfig);
|
|
741
761
|
const output = {
|
|
742
762
|
model: this.model,
|
|
743
763
|
stop_sequences: options?.stop ?? this.stopSequences,
|
|
744
764
|
stream: this.streaming,
|
|
745
765
|
max_tokens: this.maxTokens,
|
|
746
|
-
tools: this.formatStructuredToolToAnthropic(options?.tools),
|
|
766
|
+
tools: this.formatStructuredToolToAnthropic(options?.tools, { strict: options?.strict }),
|
|
747
767
|
tool_choice,
|
|
748
768
|
thinking: this.thinking,
|
|
749
769
|
context_management: this.contextManagement,
|
|
750
770
|
...this.invocationKwargs,
|
|
751
771
|
container: options?.container,
|
|
752
|
-
betas: _combineBetas(this.betas, options?.betas, toolBetas ?? [], compactionBetas),
|
|
772
|
+
betas: _combineBetas(this.betas, options?.betas, toolBetas ?? [], compactionBetas, taskBudgetBetas),
|
|
753
773
|
output_config: mergedOutputConfig,
|
|
754
774
|
inference_geo: options?.inferenceGeo ?? this.inferenceGeo,
|
|
755
|
-
mcp_servers: options?.mcp_servers
|
|
775
|
+
mcp_servers: options?.mcp_servers,
|
|
776
|
+
cache_control: options?.cache_control
|
|
756
777
|
};
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
778
|
+
require_params.validateInvocationParamCompatibility({
|
|
779
|
+
model: this.model,
|
|
780
|
+
thinking: this.thinking,
|
|
781
|
+
topK: this.topK,
|
|
782
|
+
topP: this.topP,
|
|
783
|
+
temperature: this.temperature
|
|
784
|
+
});
|
|
785
|
+
Object.assign(output, require_params.getSamplingParams({
|
|
786
|
+
model: this.model,
|
|
787
|
+
thinking: this.thinking,
|
|
788
|
+
topK: this.topK,
|
|
789
|
+
topP: this.topP,
|
|
790
|
+
temperature: this.temperature
|
|
791
|
+
}));
|
|
766
792
|
return output;
|
|
767
793
|
}
|
|
768
794
|
/** @ignore */
|
|
@@ -783,8 +809,7 @@ var ChatAnthropicMessages = class extends _langchain_core_language_models_chat_m
|
|
|
783
809
|
}
|
|
784
810
|
async *_streamResponseChunks(messages, options, runManager) {
|
|
785
811
|
const params = this.invocationParams(options);
|
|
786
|
-
|
|
787
|
-
if (options.cache_control) formattedMessages = require_message_inputs.applyCacheControlToPayload(formattedMessages, options.cache_control);
|
|
812
|
+
const formattedMessages = require_message_inputs._convertMessagesToAnthropicPayload(messages);
|
|
788
813
|
const payload = {
|
|
789
814
|
...params,
|
|
790
815
|
...formattedMessages,
|
|
@@ -837,8 +862,7 @@ var ChatAnthropicMessages = class extends _langchain_core_language_models_chat_m
|
|
|
837
862
|
*/
|
|
838
863
|
async *_streamChatModelEvents(messages, options, _runManager) {
|
|
839
864
|
const params = this.invocationParams(options);
|
|
840
|
-
|
|
841
|
-
if (options.cache_control) formattedMessages = require_message_inputs.applyCacheControlToPayload(formattedMessages, options.cache_control);
|
|
865
|
+
const formattedMessages = require_message_inputs._convertMessagesToAnthropicPayload(messages);
|
|
842
866
|
const payload = {
|
|
843
867
|
...params,
|
|
844
868
|
...formattedMessages,
|
|
@@ -861,9 +885,8 @@ var ChatAnthropicMessages = class extends _langchain_core_language_models_chat_m
|
|
|
861
885
|
yield* require_stream_events.convertAnthropicStream(abortableStream(stream, options.signal), { streamUsage: shouldStreamUsage ?? true });
|
|
862
886
|
}
|
|
863
887
|
/** @ignore */
|
|
864
|
-
async _generateNonStreaming(messages, params, requestOptions
|
|
865
|
-
|
|
866
|
-
if (cacheControl) formattedMessages = require_message_inputs.applyCacheControlToPayload(formattedMessages, cacheControl);
|
|
888
|
+
async _generateNonStreaming(messages, params, requestOptions) {
|
|
889
|
+
const formattedMessages = require_message_inputs._convertMessagesToAnthropicPayload(messages);
|
|
867
890
|
const { content, ...additionalKwargs } = await this.completionWithRetry({
|
|
868
891
|
...params,
|
|
869
892
|
stream: false,
|
|
@@ -894,7 +917,7 @@ var ChatAnthropicMessages = class extends _langchain_core_language_models_chat_m
|
|
|
894
917
|
} else return this._generateNonStreaming(messages, params, {
|
|
895
918
|
signal: options.signal,
|
|
896
919
|
headers: options.headers
|
|
897
|
-
}
|
|
920
|
+
});
|
|
898
921
|
}
|
|
899
922
|
/**
|
|
900
923
|
* Creates a streaming request with retry.
|
|
@@ -994,6 +1017,7 @@ var ChatAnthropicMessages = class extends _langchain_core_language_models_chat_m
|
|
|
994
1017
|
schema: outputSchema
|
|
995
1018
|
};
|
|
996
1019
|
let method = config?.method ?? "functionCalling";
|
|
1020
|
+
if (config?.strict !== void 0 && method !== "functionCalling") throw new Error(`Argument \`strict\` is only supported for \`method\` = "functionCalling" on Anthropic models. Got method = "${method}".`);
|
|
997
1021
|
if (method === "jsonMode") {
|
|
998
1022
|
console.warn(`"jsonMode" is not supported for Anthropic models. Falling back to "jsonSchema".`);
|
|
999
1023
|
method = "jsonSchema";
|
|
@@ -1040,7 +1064,8 @@ var ChatAnthropicMessages = class extends _langchain_core_language_models_chat_m
|
|
|
1040
1064
|
ls_structured_output_format: {
|
|
1041
1065
|
kwargs: { method: "functionCalling" },
|
|
1042
1066
|
schema: (0, _langchain_core_utils_json_schema.toJsonSchema)(schema)
|
|
1043
|
-
}
|
|
1067
|
+
},
|
|
1068
|
+
...config?.strict !== void 0 ? { strict: config.strict } : {}
|
|
1044
1069
|
});
|
|
1045
1070
|
const raiseIfNoToolCalls = (message) => {
|
|
1046
1071
|
if (!message.tool_calls || message.tool_calls.length === 0) throw new Error(thinkingAdmonition);
|
|
@@ -1057,7 +1082,8 @@ var ChatAnthropicMessages = class extends _langchain_core_language_models_chat_m
|
|
|
1057
1082
|
ls_structured_output_format: {
|
|
1058
1083
|
kwargs: { method: "functionCalling" },
|
|
1059
1084
|
schema: (0, _langchain_core_utils_json_schema.toJsonSchema)(schema)
|
|
1060
|
-
}
|
|
1085
|
+
},
|
|
1086
|
+
...config?.strict !== void 0 ? { strict: config.strict } : {}
|
|
1061
1087
|
});
|
|
1062
1088
|
} else throw new TypeError(`Unrecognized structured output method '${method}'. Expected 'functionCalling' or 'jsonSchema'`);
|
|
1063
1089
|
return (0, _langchain_core_language_models_structured_output.assembleStructuredOutputPipeline)(llm, outputParser, includeRaw, includeRaw ? "StructuredOutputRunnable" : "ChatAnthropicStructuredOutput");
|