| import type { FinishReason } from '../types/language-model'; | ||
| export function isToolExecutionAllowedFinishReason( | ||
| finishReason: FinishReason, | ||
| ): boolean { | ||
| return finishReason === 'stop' || finishReason === 'tool-calls'; | ||
| } |
+3
-3
| { | ||
| "name": "ai", | ||
| "version": "7.0.69", | ||
| "version": "7.0.70", | ||
| "type": "module", | ||
@@ -45,5 +45,5 @@ "description": "AI SDK by Vercel - build apps like ChatGPT, Claude, Gemini, and more with a single interface for any model using the Vercel AI Gateway or go direct to OpenAI, Anthropic, Google, or any other model provider.", | ||
| "dependencies": { | ||
| "@ai-sdk/gateway": "4.0.55", | ||
| "@ai-sdk/gateway": "4.0.56", | ||
| "@ai-sdk/provider": "4.0.7", | ||
| "@ai-sdk/provider-utils": "5.0.27" | ||
| "@ai-sdk/provider-utils": "5.0.28" | ||
| }, | ||
@@ -50,0 +50,0 @@ "devDependencies": { |
@@ -71,2 +71,8 @@ import type { | ||
| async function markPromiseAsHandled<T>(promise: Promise<T>): Promise<void> { | ||
| try { | ||
| await promise; | ||
| } catch {} | ||
| } | ||
| /** | ||
@@ -660,2 +666,3 @@ * Callback that is set using the `onError` option. | ||
| let error: unknown | undefined; | ||
| let terminalError: { error: unknown } | undefined; | ||
| let msToFirstChunk: number | undefined = undefined; | ||
@@ -756,2 +763,15 @@ | ||
| case 'error': { | ||
| if (terminalError === undefined) { | ||
| const wrappedError = wrapGatewayError(chunk.error); | ||
| terminalError = { error: wrappedError }; | ||
| error = wrappedError; | ||
| finishReason = 'error'; | ||
| self.rejectResultPromises(wrappedError); | ||
| } | ||
| controller.enqueue(chunk); | ||
| break; | ||
| } | ||
| case 'finish': { | ||
@@ -762,3 +782,6 @@ if (textDelta !== '') { | ||
| finishReason = chunk.finishReason.unified; | ||
| finishReason = | ||
| terminalError === undefined | ||
| ? chunk.finishReason.unified | ||
| : 'error'; | ||
@@ -770,3 +793,3 @@ usage = asLanguageModelUsage(chunk.usage); | ||
| ...chunk, | ||
| finishReason: chunk.finishReason.unified, | ||
| finishReason, | ||
| usage, | ||
@@ -782,2 +805,6 @@ response: fullResponse, | ||
| if (terminalError !== undefined) { | ||
| break; | ||
| } | ||
| self._usage.resolve(usage); | ||
@@ -876,5 +903,15 @@ self._providerMetadata.resolve(providerMetadata); | ||
| stitchableStream.addStream(transformedStream); | ||
| stitchableStream.addStream(transformedStream, { | ||
| onError(error) { | ||
| const wrappedError = wrapGatewayError(error); | ||
| self.rejectResultPromises(wrappedError); | ||
| void notify({ | ||
| event: { error: wrappedError }, | ||
| callbacks: onError, | ||
| }); | ||
| }, | ||
| }); | ||
| })() | ||
| .catch(async error => { | ||
| self.rejectResultPromises(error); | ||
| await telemetryDispatcher.onError?.({ callId, error }); | ||
@@ -898,2 +935,25 @@ | ||
| private rejectResultPromises(error: unknown) { | ||
| this.rejectResultPromise({ delayedPromise: this._object, error }); | ||
| this.rejectResultPromise({ delayedPromise: this._usage, error }); | ||
| this.rejectResultPromise({ delayedPromise: this._providerMetadata, error }); | ||
| this.rejectResultPromise({ delayedPromise: this._warnings, error }); | ||
| this.rejectResultPromise({ delayedPromise: this._request, error }); | ||
| this.rejectResultPromise({ delayedPromise: this._response, error }); | ||
| this.rejectResultPromise({ delayedPromise: this._finishReason, error }); | ||
| } | ||
| private rejectResultPromise<T>({ | ||
| delayedPromise, | ||
| error, | ||
| }: { | ||
| delayedPromise: DelayedPromise<T>; | ||
| error: unknown; | ||
| }) { | ||
| if (delayedPromise.isPending()) { | ||
| delayedPromise.reject(error); | ||
| markPromiseAsHandled(delayedPromise.promise); | ||
| } | ||
| } | ||
| get object() { | ||
@@ -900,0 +960,0 @@ return this._object.promise; |
@@ -14,2 +14,3 @@ import type { | ||
| import { executeToolCall } from './execute-tool-call'; | ||
| import { isToolExecutionAllowedFinishReason } from './is-tool-execution-allowed-finish-reason'; | ||
| import { resolveToolApproval } from './resolve-tool-approval'; | ||
@@ -201,2 +202,6 @@ import type { LanguageModelStreamPart } from './stream-language-model-call'; | ||
| case 'model-call-end': { | ||
| if (!isToolExecutionAllowedFinishReason(chunk.finishReason)) { | ||
| return; | ||
| } | ||
| await Promise.all( | ||
@@ -203,0 +208,0 @@ toolCallsToExecute.map(async toolCall => { |
@@ -187,2 +187,5 @@ import type { JSONObject } from '@ai-sdk/provider'; | ||
| z.looseObject({ | ||
| type: z.literal('reset-step'), | ||
| }), | ||
| z.looseObject({ | ||
| type: z.literal('start'), | ||
@@ -383,2 +386,8 @@ messageId: z.string().optional(), | ||
| | { | ||
| /** | ||
| * Removes all message parts added during the current step. | ||
| */ | ||
| type: 'reset-step'; | ||
| } | ||
| | { | ||
| type: 'start'; | ||
@@ -385,0 +394,0 @@ messageId?: string; |
@@ -66,3 +66,3 @@ import { | ||
| part.state === 'approval-responded' || | ||
| part.state === 'output-available' || | ||
| (part.state === 'output-available' && part.preliminary !== true) || | ||
| part.state === 'output-error' || | ||
@@ -69,0 +69,0 @@ part.state === 'output-denied', |
@@ -890,2 +890,19 @@ import type { JSONObject } from '@ai-sdk/provider'; | ||
| case 'reset-step': { | ||
| const currentStepParts = getCurrentStepParts(); | ||
| state.activeTextParts = createIdMap(); | ||
| state.activeReasoningParts = createIdMap(); | ||
| state.partialToolCalls = createIdMap(); | ||
| if (currentStepParts.length > 0) { | ||
| state.message.parts.splice( | ||
| state.message.parts.length - currentStepParts.length, | ||
| currentStepParts.length, | ||
| ); | ||
| write(); | ||
| } | ||
| break; | ||
| } | ||
| case 'start': { | ||
@@ -892,0 +909,0 @@ if (chunk.messageId != null) { |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
6705497
0.19%628
0.16%69638
0.24%+ Added
+ Added
- Removed
- Removed
Updated