ai 6.0.312 → 6.0.314
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 +19 -0
- package/dist/index.d.mts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +85 -18
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +85 -18
- package/dist/index.mjs.map +1 -1
- package/dist/internal/index.js +1 -1
- package/dist/internal/index.mjs +1 -1
- package/docs/03-ai-sdk-core/15-tools-and-tool-calling.mdx +6 -0
- package/docs/03-ai-sdk-core/37-speech.mdx +1 -0
- package/docs/07-reference/05-ai-sdk-errors/ai-tool-choice-violation-error.mdx +11 -6
- package/package.json +2 -2
- package/src/error/tool-choice-violation-error.ts +6 -4
- package/src/generate-text/collect-tool-approvals.ts +10 -0
- package/src/generate-text/generate-text.ts +14 -10
- package/src/generate-text/prune-messages.ts +85 -32
- package/src/generate-text/run-tools-transformation.ts +53 -1
- package/src/generate-text/stream-text.ts +1 -0
- package/src/ui/process-ui-message-stream.ts +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# ai
|
|
2
2
|
|
|
3
|
+
## 6.0.314
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 6572f26: Fix `toolChoice: 'none'` by forwarding it to the Hugging Face Responses API and rejecting tool calls before local execution in `generateText` and `streamText`. Streamed tool parts are withheld so client-side tools cannot act on them, and `experimental_repairToolCall` is not invoked for rejected tool calls.
|
|
8
|
+
|
|
9
|
+
## 6.0.313
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- 52803fb: fix(ai): process only the first approval response per tool call, so repeated or conflicting responses in the final tool message no longer execute a tool twice or both execute and deny it
|
|
14
|
+
- a0f7494: fix(ai): remove orphaned reasoning, including consecutive reasoning parts, when pruning tool calls
|
|
15
|
+
- a48e8a9: fix(ai): preserve repaired tool names in streamed UI message parts
|
|
16
|
+
- Updated dependencies [fa49238]
|
|
17
|
+
- Updated dependencies [d301a16]
|
|
18
|
+
- Updated dependencies [965effe]
|
|
19
|
+
- Updated dependencies [4f82ab0]
|
|
20
|
+
- @ai-sdk/gateway@3.0.220
|
|
21
|
+
|
|
3
22
|
## 6.0.312
|
|
4
23
|
|
|
5
24
|
### Patch Changes
|
package/dist/index.d.mts
CHANGED
|
@@ -4985,6 +4985,8 @@ declare class NoVideoGeneratedError extends AISDKError {
|
|
|
4985
4985
|
|
|
4986
4986
|
declare const symbol$7: unique symbol;
|
|
4987
4987
|
type EnforcedToolChoice = Extract<LanguageModelV3ToolChoice, {
|
|
4988
|
+
type: 'none';
|
|
4989
|
+
} | {
|
|
4988
4990
|
type: 'required';
|
|
4989
4991
|
} | {
|
|
4990
4992
|
type: 'tool';
|
package/dist/index.d.ts
CHANGED
|
@@ -4985,6 +4985,8 @@ declare class NoVideoGeneratedError extends AISDKError {
|
|
|
4985
4985
|
|
|
4986
4986
|
declare const symbol$7: unique symbol;
|
|
4987
4987
|
type EnforcedToolChoice = Extract<LanguageModelV3ToolChoice, {
|
|
4988
|
+
type: 'none';
|
|
4989
|
+
} | {
|
|
4988
4990
|
type: 'required';
|
|
4989
4991
|
} | {
|
|
4990
4992
|
type: 'tool';
|
package/dist/index.js
CHANGED
|
@@ -521,7 +521,7 @@ var ToolChoiceViolationError = class extends import_provider15.AISDKError {
|
|
|
521
521
|
provider,
|
|
522
522
|
modelId,
|
|
523
523
|
content,
|
|
524
|
-
message = toolChoice.type === "required" ? "Model response did not contain a tool call even though tool choice was required." : `Model response did not contain a call to the required tool '${toolChoice.toolName}'.`
|
|
524
|
+
message = toolChoice.type === "none" ? "Model response contained a tool call even though tool choice was none." : toolChoice.type === "required" ? "Model response did not contain a tool call even though tool choice was required." : `Model response did not contain a call to the required tool '${toolChoice.toolName}'.`
|
|
525
525
|
}) {
|
|
526
526
|
super({ name: name15, message });
|
|
527
527
|
this[_a15] = true;
|
|
@@ -1335,7 +1335,7 @@ function detectMediaType({
|
|
|
1335
1335
|
var import_provider_utils3 = require("@ai-sdk/provider-utils");
|
|
1336
1336
|
|
|
1337
1337
|
// src/version.ts
|
|
1338
|
-
var VERSION = true ? "6.0.
|
|
1338
|
+
var VERSION = true ? "6.0.314" : "0.0.0-test";
|
|
1339
1339
|
|
|
1340
1340
|
// src/util/download/download.ts
|
|
1341
1341
|
var download = async ({
|
|
@@ -2976,6 +2976,7 @@ function collectToolApprovals({
|
|
|
2976
2976
|
}
|
|
2977
2977
|
const approvedToolApprovals = [];
|
|
2978
2978
|
const deniedToolApprovals = [];
|
|
2979
|
+
const collectedToolCallIds = /* @__PURE__ */ new Set();
|
|
2979
2980
|
const approvalResponses = lastMessage.content.filter(
|
|
2980
2981
|
(part) => part.type === "tool-approval-response"
|
|
2981
2982
|
);
|
|
@@ -2996,6 +2997,10 @@ function collectToolApprovals({
|
|
|
2996
2997
|
approvalId: approvalRequest.approvalId
|
|
2997
2998
|
});
|
|
2998
2999
|
}
|
|
3000
|
+
if (collectedToolCallIds.has(toolCall.toolCallId)) {
|
|
3001
|
+
continue;
|
|
3002
|
+
}
|
|
3003
|
+
collectedToolCallIds.add(toolCall.toolCallId);
|
|
2999
3004
|
const approval = {
|
|
3000
3005
|
approvalRequest,
|
|
3001
3006
|
approvalResponse,
|
|
@@ -5040,16 +5045,18 @@ async function generateText({
|
|
|
5040
5045
|
(toolCall) => parseToolCall({
|
|
5041
5046
|
toolCall,
|
|
5042
5047
|
tools: stepToolSet,
|
|
5043
|
-
|
|
5048
|
+
// tool calls are rejected with tool choice none,
|
|
5049
|
+
// so user callbacks must not process them:
|
|
5050
|
+
repairToolCall: (stepToolChoice == null ? void 0 : stepToolChoice.type) === "none" ? void 0 : repairToolCall,
|
|
5044
5051
|
system,
|
|
5045
5052
|
messages: stepInputMessages
|
|
5046
5053
|
})
|
|
5047
5054
|
)
|
|
5048
5055
|
);
|
|
5049
|
-
const enforcedToolChoice = (stepToolChoice == null ? void 0 : stepToolChoice.type) === "
|
|
5050
|
-
if (enforcedToolChoice != null && !stepToolCalls.some(
|
|
5056
|
+
const enforcedToolChoice = (stepToolChoice == null ? void 0 : stepToolChoice.type) === "auto" ? void 0 : stepToolChoice;
|
|
5057
|
+
if (enforcedToolChoice != null && (enforcedToolChoice.type === "none" ? stepToolCalls.length > 0 : !stepToolCalls.some(
|
|
5051
5058
|
(toolCall) => enforcedToolChoice.type === "required" || toolCall.toolName === enforcedToolChoice.toolName
|
|
5052
|
-
)) {
|
|
5059
|
+
))) {
|
|
5053
5060
|
throw new ToolChoiceViolationError({
|
|
5054
5061
|
toolChoice: enforcedToolChoice,
|
|
5055
5062
|
finishReason: currentModelResponse.finishReason.unified,
|
|
@@ -6148,6 +6155,7 @@ function processUIMessageStream({
|
|
|
6148
6155
|
const anyPart = part;
|
|
6149
6156
|
if (part != null) {
|
|
6150
6157
|
part.state = options.state;
|
|
6158
|
+
anyPart.type = `tool-${options.toolName}`;
|
|
6151
6159
|
anyPart.input = anyOptions.input;
|
|
6152
6160
|
anyPart.output = anyOptions.output;
|
|
6153
6161
|
anyPart.errorText = anyOptions.errorText;
|
|
@@ -7100,6 +7108,7 @@ function createStitchableStream() {
|
|
|
7100
7108
|
var import_provider_utils19 = require("@ai-sdk/provider-utils");
|
|
7101
7109
|
function runToolsTransformation({
|
|
7102
7110
|
tools,
|
|
7111
|
+
toolChoice,
|
|
7103
7112
|
generatorStream,
|
|
7104
7113
|
tracer,
|
|
7105
7114
|
telemetry,
|
|
@@ -7189,10 +7198,19 @@ function runToolsTransformation({
|
|
|
7189
7198
|
});
|
|
7190
7199
|
}
|
|
7191
7200
|
const activeToolCallToolNames = /* @__PURE__ */ new Map();
|
|
7201
|
+
const withholdToolParts = (toolChoice == null ? void 0 : toolChoice.type) === "none";
|
|
7202
|
+
const withheldToolContent = [];
|
|
7192
7203
|
const forwardStream = new TransformStream({
|
|
7193
7204
|
async transform(chunk, controller) {
|
|
7194
|
-
var _a23, _b, _c, _d;
|
|
7205
|
+
var _a23, _b, _c, _d, _e, _f;
|
|
7195
7206
|
const chunkType = chunk.type;
|
|
7207
|
+
if (withholdToolParts && (chunkType === "tool-input-start" || chunkType === "tool-input-delta" || chunkType === "tool-input-end" || chunkType === "tool-approval-request")) {
|
|
7208
|
+
return;
|
|
7209
|
+
}
|
|
7210
|
+
if (withholdToolParts && (chunkType === "tool-call" || chunkType === "tool-result")) {
|
|
7211
|
+
withheldToolContent.push(chunk);
|
|
7212
|
+
return;
|
|
7213
|
+
}
|
|
7196
7214
|
switch (chunkType) {
|
|
7197
7215
|
case "stream-start":
|
|
7198
7216
|
case "text-start":
|
|
@@ -7250,13 +7268,26 @@ function runToolsTransformation({
|
|
|
7250
7268
|
break;
|
|
7251
7269
|
}
|
|
7252
7270
|
case "finish": {
|
|
7271
|
+
const toolChoiceViolationError = withholdToolParts && withheldToolContent.some((part) => part.type === "tool-call") ? new ToolChoiceViolationError({
|
|
7272
|
+
toolChoice: { type: "none" },
|
|
7273
|
+
finishReason: chunk.finishReason.unified,
|
|
7274
|
+
provider: (_e = model == null ? void 0 : model.provider) != null ? _e : "unknown",
|
|
7275
|
+
modelId: (_f = model == null ? void 0 : model.modelId) != null ? _f : "unknown",
|
|
7276
|
+
content: withheldToolContent
|
|
7277
|
+
}) : void 0;
|
|
7253
7278
|
finishChunk = {
|
|
7254
7279
|
type: "finish",
|
|
7255
|
-
finishReason: chunk.finishReason.unified,
|
|
7280
|
+
finishReason: toolChoiceViolationError == null ? chunk.finishReason.unified : "error",
|
|
7256
7281
|
rawFinishReason: chunk.finishReason.raw,
|
|
7257
7282
|
usage: asLanguageModelUsage(chunk.usage),
|
|
7258
7283
|
providerMetadata: chunk.providerMetadata
|
|
7259
7284
|
};
|
|
7285
|
+
if (toolChoiceViolationError != null) {
|
|
7286
|
+
controller.enqueue({
|
|
7287
|
+
type: "error",
|
|
7288
|
+
error: toolChoiceViolationError
|
|
7289
|
+
});
|
|
7290
|
+
}
|
|
7260
7291
|
if (isToolExecutionAllowedFinishReason(chunk.finishReason.unified)) {
|
|
7261
7292
|
for (const toolCall of toolCallsToExecute.splice(0)) {
|
|
7262
7293
|
executeToolCallAfterFinish(toolCall);
|
|
@@ -8445,6 +8476,7 @@ var DefaultStreamTextResult = class {
|
|
|
8445
8476
|
);
|
|
8446
8477
|
const streamWithToolResults = runToolsTransformation({
|
|
8447
8478
|
tools: stepToolSet,
|
|
8479
|
+
toolChoice: stepToolChoice,
|
|
8448
8480
|
generatorStream: stream2,
|
|
8449
8481
|
tracer,
|
|
8450
8482
|
telemetry,
|
|
@@ -12840,18 +12872,53 @@ function pruneMessages({
|
|
|
12840
12872
|
if (message.role !== "assistant" && message.role !== "tool" || typeof message.content === "string" || keepLastMessagesCount && messageIndex >= messages.length - keepLastMessagesCount) {
|
|
12841
12873
|
return message;
|
|
12842
12874
|
}
|
|
12843
|
-
|
|
12844
|
-
|
|
12845
|
-
|
|
12846
|
-
|
|
12847
|
-
|
|
12875
|
+
const keepParts = message.content.map((part) => {
|
|
12876
|
+
if (part.type !== "tool-call" && part.type !== "tool-result" && part.type !== "tool-approval-request" && part.type !== "tool-approval-response") {
|
|
12877
|
+
return true;
|
|
12878
|
+
}
|
|
12879
|
+
if ((part.type === "tool-call" || part.type === "tool-result") && keptToolCallIds.has(part.toolCallId) || (part.type === "tool-approval-request" || part.type === "tool-approval-response") && keptApprovalIds.has(part.approvalId)) {
|
|
12880
|
+
return true;
|
|
12881
|
+
}
|
|
12882
|
+
const partToolName = part.type === "tool-call" || part.type === "tool-result" ? part.toolName : approvalIdToToolName.get(part.approvalId);
|
|
12883
|
+
return toolCall.tools != null && partToolName != null && !toolCall.tools.includes(partToolName);
|
|
12884
|
+
});
|
|
12885
|
+
if (message.role === "assistant") {
|
|
12886
|
+
for (let reasoningIndex = 0; reasoningIndex < message.content.length; reasoningIndex++) {
|
|
12887
|
+
const part = message.content[reasoningIndex];
|
|
12888
|
+
if (part.type !== "reasoning") {
|
|
12889
|
+
continue;
|
|
12890
|
+
}
|
|
12891
|
+
let reasoningEndIndex = reasoningIndex + 1;
|
|
12892
|
+
while (reasoningEndIndex < message.content.length) {
|
|
12893
|
+
const nextPart = message.content[reasoningEndIndex];
|
|
12894
|
+
if (nextPart.type !== "reasoning") {
|
|
12895
|
+
break;
|
|
12896
|
+
}
|
|
12897
|
+
reasoningEndIndex++;
|
|
12848
12898
|
}
|
|
12849
|
-
|
|
12850
|
-
|
|
12899
|
+
let followingPartIndex = reasoningEndIndex;
|
|
12900
|
+
let hasFollowingPart = false;
|
|
12901
|
+
let hasKeptFollowingPart = false;
|
|
12902
|
+
while (followingPartIndex < message.content.length) {
|
|
12903
|
+
const followingPart = message.content[followingPartIndex];
|
|
12904
|
+
if (followingPart.type === "reasoning") {
|
|
12905
|
+
break;
|
|
12906
|
+
}
|
|
12907
|
+
hasFollowingPart = true;
|
|
12908
|
+
hasKeptFollowingPart || (hasKeptFollowingPart = keepParts[followingPartIndex]);
|
|
12909
|
+
followingPartIndex++;
|
|
12851
12910
|
}
|
|
12852
|
-
|
|
12853
|
-
|
|
12854
|
-
|
|
12911
|
+
if (hasFollowingPart && !hasKeptFollowingPart) {
|
|
12912
|
+
for (let index = reasoningIndex; index < reasoningEndIndex; index++) {
|
|
12913
|
+
keepParts[index] = false;
|
|
12914
|
+
}
|
|
12915
|
+
}
|
|
12916
|
+
reasoningIndex = followingPartIndex - 1;
|
|
12917
|
+
}
|
|
12918
|
+
}
|
|
12919
|
+
return {
|
|
12920
|
+
...message,
|
|
12921
|
+
content: message.content.filter((_, index) => keepParts[index])
|
|
12855
12922
|
};
|
|
12856
12923
|
});
|
|
12857
12924
|
}
|