ai 7.0.97 → 7.0.98

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.
@@ -1,12 +1,18 @@
1
- import type { JSONObject, RerankingModelV4CallOptions } from '@ai-sdk/provider';
1
+ import {
2
+ InvalidResponseDataError,
3
+ type JSONObject,
4
+ type RerankingModelV4CallOptions,
5
+ type RerankingModelV4Result,
6
+ } from '@ai-sdk/provider';
2
7
  import {
3
8
  createIdGenerator,
9
+ type Context,
4
10
  type ProviderOptions,
5
11
  } from '@ai-sdk/provider-utils';
6
12
  import { prepareRetries } from '../../src/util/prepare-retries';
7
13
  import { logWarnings } from '../logger/log-warnings';
8
14
  import { resolveRerankingModel } from '../model/resolve-model';
9
- import { createTelemetryDispatcher } from '../telemetry/create-telemetry-dispatcher';
15
+ import { createRestrictedTelemetryDispatcher } from './restricted-telemetry-dispatcher';
10
16
  import type { TelemetryOptions } from '../telemetry/telemetry-options';
11
17
  import type { RerankingModel } from '../types';
12
18
  import type { Callback } from '../util/callback';
@@ -32,10 +38,14 @@ const originalGenerateCallId = createIdGenerator({
32
38
  * @param headers - Additional HTTP headers to be sent with the request. Only applicable for HTTP-based providers.
33
39
  * @param providerOptions - Additional provider-specific options.
34
40
  * @param telemetry - Optional telemetry configuration.
41
+ * @param runtimeContext - User-defined runtime context passed to callbacks and, when explicitly included, telemetry.
35
42
  *
36
43
  * @returns A result object that contains the reranked documents, the reranked indices, and additional information.
37
44
  */
38
- export async function rerank<VALUE extends JSONObject | string>({
45
+ export async function rerank<
46
+ VALUE extends JSONObject | string,
47
+ RUNTIME_CONTEXT extends Context = Context,
48
+ >({
39
49
  model: modelArg,
40
50
  documents,
41
51
  query,
@@ -46,6 +56,7 @@ export async function rerank<VALUE extends JSONObject | string>({
46
56
  providerOptions,
47
57
  experimental_telemetry,
48
58
  telemetry = experimental_telemetry,
59
+ runtimeContext = {} as RUNTIME_CONTEXT,
49
60
  onStart,
50
61
  experimental_onStart,
51
62
  onEnd,
@@ -93,14 +104,19 @@ export async function rerank<VALUE extends JSONObject | string>({
93
104
  /**
94
105
  * Optional telemetry configuration.
95
106
  */
96
- telemetry?: TelemetryOptions;
107
+ telemetry?: TelemetryOptions<RUNTIME_CONTEXT>;
97
108
 
98
109
  /**
99
110
  * Optional telemetry configuration.
100
111
  *
101
112
  * @deprecated Use `telemetry` instead. This alias will be removed in a future major release.
102
113
  */
103
- experimental_telemetry?: TelemetryOptions;
114
+ experimental_telemetry?: TelemetryOptions<RUNTIME_CONTEXT>;
115
+
116
+ /**
117
+ * User-defined runtime context. Treat runtime context as immutable.
118
+ */
119
+ runtimeContext?: RUNTIME_CONTEXT;
104
120
 
105
121
  /**
106
122
  * Additional provider-specific options. They are passed through
@@ -113,7 +129,7 @@ export async function rerank<VALUE extends JSONObject | string>({
113
129
  * Callback that is called when the rerank operation begins,
114
130
  * before the reranking model is called.
115
131
  */
116
- onStart?: Callback<RerankStartEvent>;
132
+ onStart?: Callback<RerankStartEvent<RUNTIME_CONTEXT>>;
117
133
 
118
134
  /**
119
135
  * Callback that is called when the rerank operation begins,
@@ -121,13 +137,13 @@ export async function rerank<VALUE extends JSONObject | string>({
121
137
  *
122
138
  * @deprecated Use `onStart` instead.
123
139
  */
124
- experimental_onStart?: Callback<RerankStartEvent>;
140
+ experimental_onStart?: Callback<RerankStartEvent<RUNTIME_CONTEXT>>;
125
141
 
126
142
  /**
127
143
  * Callback that is called when the rerank operation completes,
128
144
  * after the reranking model returns.
129
145
  */
130
- onEnd?: Callback<RerankEndEvent>;
146
+ onEnd?: Callback<RerankEndEvent<RUNTIME_CONTEXT>>;
131
147
 
132
148
  /**
133
149
  * Callback that is called when the rerank operation completes,
@@ -135,7 +151,7 @@ export async function rerank<VALUE extends JSONObject | string>({
135
151
  *
136
152
  * @deprecated Use `onEnd` instead.
137
153
  */
138
- experimental_onEnd?: Callback<RerankEndEvent>;
154
+ experimental_onEnd?: Callback<RerankEndEvent<RUNTIME_CONTEXT>>;
139
155
 
140
156
  /**
141
157
  * Internal. For test use only. May change without notice.
@@ -149,7 +165,7 @@ export async function rerank<VALUE extends JSONObject | string>({
149
165
  const resolvedOnStart = onStart ?? experimental_onStart;
150
166
  const resolvedOnEnd = onEnd ?? experimental_onEnd;
151
167
 
152
- const telemetryDispatcher = createTelemetryDispatcher({
168
+ const telemetryDispatcher = createRestrictedTelemetryDispatcher({
153
169
  telemetry,
154
170
  });
155
171
 
@@ -163,6 +179,7 @@ export async function rerank<VALUE extends JSONObject | string>({
163
179
  event: {
164
180
  callId,
165
181
  operationId: 'ai.rerank',
182
+ runtimeContext,
166
183
  provider: model.provider,
167
184
  modelId: model.modelId,
168
185
  documents,
@@ -179,6 +196,7 @@ export async function rerank<VALUE extends JSONObject | string>({
179
196
  event: {
180
197
  callId,
181
198
  operationId: 'ai.rerank',
199
+ runtimeContext,
182
200
  provider: model.provider,
183
201
  modelId: model.modelId,
184
202
  documents,
@@ -218,6 +236,7 @@ export async function rerank<VALUE extends JSONObject | string>({
218
236
  const startEvent = {
219
237
  callId,
220
238
  operationId: 'ai.rerank',
239
+ runtimeContext,
221
240
  provider: model.provider,
222
241
  modelId: model.modelId,
223
242
  documents,
@@ -286,6 +305,8 @@ export async function rerank<VALUE extends JSONObject | string>({
286
305
  },
287
306
  );
288
307
 
308
+ validateRankingIndices({ ranking, documents });
309
+
289
310
  logWarnings({
290
311
  warnings: warnings ?? [],
291
312
  provider: model.provider,
@@ -296,14 +317,15 @@ export async function rerank<VALUE extends JSONObject | string>({
296
317
  event: {
297
318
  callId,
298
319
  operationId: 'ai.rerank',
320
+ runtimeContext,
299
321
  provider: model.provider,
300
322
  modelId: model.modelId,
301
323
  documents,
302
324
  query,
303
- ranking: ranking.map(r => ({
304
- originalIndex: r.index,
305
- score: r.relevanceScore,
306
- document: documents[r.index],
325
+ ranking: ranking.map(ranking => ({
326
+ originalIndex: ranking.index,
327
+ score: ranking.relevanceScore,
328
+ document: documents[ranking.index],
307
329
  })),
308
330
  warnings: warnings ?? [],
309
331
  providerMetadata,
@@ -342,6 +364,23 @@ export async function rerank<VALUE extends JSONObject | string>({
342
364
  });
343
365
  }
344
366
 
367
+ function validateRankingIndices<VALUE>({
368
+ ranking,
369
+ documents,
370
+ }: {
371
+ ranking: RerankingModelV4Result['ranking'];
372
+ documents: Array<VALUE>;
373
+ }) {
374
+ for (const { index } of ranking) {
375
+ if (!Number.isInteger(index) || index < 0 || index >= documents.length) {
376
+ throw new InvalidResponseDataError({
377
+ data: ranking,
378
+ message: `Invalid ranking index ${index}. Expected an integer between 0 and ${documents.length - 1}.`,
379
+ });
380
+ }
381
+ }
382
+ }
383
+
345
384
  class DefaultRerankResult<VALUE> implements RerankResult<VALUE> {
346
385
  readonly originalDocuments: RerankResult<VALUE>['originalDocuments'];
347
386
  readonly ranking: RerankResult<VALUE>['ranking'];
@@ -0,0 +1,44 @@
1
+ import type { Context } from '@ai-sdk/provider-utils';
2
+ import { createTelemetryDispatcher } from '../telemetry/create-telemetry-dispatcher';
3
+ import { filterIncludedContext } from '../telemetry/filter-included-context';
4
+ import type { TelemetryDispatcher } from '../telemetry/telemetry';
5
+ import type { TelemetryOptions } from '../telemetry/telemetry-options';
6
+ import type { Callback } from '../util/callback';
7
+ import type { RerankStartEvent, RerankEndEvent } from './rerank-events';
8
+
9
+ /**
10
+ * Filters runtime context before sending operation events to telemetry integrations.
11
+ * User callbacks continue to receive the original context.
12
+ */
13
+ export function createRestrictedTelemetryDispatcher<
14
+ RUNTIME_CONTEXT extends Context,
15
+ >({
16
+ telemetry,
17
+ }: {
18
+ telemetry?: TelemetryOptions<RUNTIME_CONTEXT>;
19
+ }): Omit<TelemetryDispatcher, 'onStart' | 'onEnd'> & {
20
+ onStart: Callback<RerankStartEvent<RUNTIME_CONTEXT>>;
21
+ onEnd: Callback<RerankEndEvent<RUNTIME_CONTEXT>>;
22
+ } {
23
+ const dispatcher = createTelemetryDispatcher({ telemetry });
24
+
25
+ return {
26
+ ...dispatcher,
27
+ onStart: event =>
28
+ dispatcher.onStart?.({
29
+ ...event,
30
+ runtimeContext: filterIncludedContext({
31
+ context: event.runtimeContext,
32
+ includeContext: telemetry?.includeRuntimeContext,
33
+ }),
34
+ }),
35
+ onEnd: event =>
36
+ dispatcher.onEnd?.({
37
+ ...event,
38
+ runtimeContext: filterIncludedContext({
39
+ context: event.runtimeContext,
40
+ includeContext: telemetry?.includeRuntimeContext,
41
+ }),
42
+ }),
43
+ };
44
+ }
@@ -0,0 +1,24 @@
1
+ import type { Context } from '@ai-sdk/provider-utils';
2
+ import type { IncludedContext } from './telemetry-options';
3
+
4
+ /**
5
+ * Returns a shallow copy of the runtime context with only top-level
6
+ * properties marked for telemetry inclusion.
7
+ */
8
+ export function filterIncludedContext<CONTEXT extends Context>({
9
+ context,
10
+ includeContext,
11
+ }: {
12
+ context: CONTEXT;
13
+ includeContext: IncludedContext<CONTEXT>;
14
+ }): Context {
15
+ if (context == null) {
16
+ return {};
17
+ }
18
+
19
+ return Object.fromEntries(
20
+ Object.entries(context).filter(
21
+ ([key]) => includeContext?.[key as keyof CONTEXT] === true,
22
+ ),
23
+ );
24
+ }
package/src/ui/index.ts CHANGED
@@ -44,6 +44,7 @@ export {
44
44
  isReasoningUIPart,
45
45
  isStaticToolUIPart,
46
46
  isTextUIPart,
47
+ isToolOutputErrorUIPart,
47
48
  isToolUIPart,
48
49
  type CustomContentUIPart,
49
50
  type DataUIPart,
@@ -57,6 +58,7 @@ export {
57
58
  type SourceUrlUIPart,
58
59
  type StepStartUIPart,
59
60
  type TextUIPart,
61
+ type ToolOutputErrorUIPart,
60
62
  type ToolUIPart,
61
63
  type UIDataTypes,
62
64
  type UIMessage,
@@ -361,7 +361,7 @@ export type UIToolInvocation<TOOL extends UITool | Tool> = {
361
361
  };
362
362
  }
363
363
  | {
364
- state: 'output-error'; // TODO AI SDK 6: change to 'error' state
364
+ state: 'output-error';
365
365
  input: asUITool<TOOL>['input'] | undefined;
366
366
  rawInput?: unknown; // TODO AI SDK 6: remove this field, input should be unknown
367
367
  output?: never;
@@ -489,7 +489,7 @@ export type DynamicToolUIPart = {
489
489
  };
490
490
  }
491
491
  | {
492
- state: 'output-error'; // TODO AI SDK 6: change to 'error' state
492
+ state: 'output-error';
493
493
  input: unknown;
494
494
  output?: never;
495
495
  errorText: string;
@@ -523,6 +523,17 @@ export type DynamicToolUIPart = {
523
523
  }
524
524
  );
525
525
 
526
+ /**
527
+ * A static or dynamic tool UI part whose execution failed.
528
+ *
529
+ * Use `isToolOutputErrorUIPart` to identify tool output errors without
530
+ * depending on the underlying tool state discriminator.
531
+ */
532
+ export type ToolOutputErrorUIPart<TOOLS extends UITools = UITools> = Extract<
533
+ ToolUIPart<TOOLS> | DynamicToolUIPart,
534
+ { state: 'output-error' }
535
+ >;
536
+
526
537
  /**
527
538
  * Type guard to check if a message part is a text part.
528
539
  */
@@ -603,6 +614,17 @@ export function isToolUIPart<TOOLS extends UITools>(
603
614
  return isStaticToolUIPart(part) || isDynamicToolUIPart(part);
604
615
  }
605
616
 
617
+ /**
618
+ * Check if a message part is a tool output error part.
619
+ *
620
+ * This works for both static and dynamic tools.
621
+ */
622
+ export function isToolOutputErrorUIPart<TOOLS extends UITools>(
623
+ part: UIMessagePart<UIDataTypes, TOOLS>,
624
+ ): part is ToolOutputErrorUIPart<TOOLS> {
625
+ return isToolUIPart(part) && part.state === 'output-error';
626
+ }
627
+
606
628
  /**
607
629
  * Returns the name of the static tool.
608
630
  *
@@ -438,10 +438,19 @@ type ValidateUIMessagesOptions<UI_MESSAGE extends UIMessage> = {
438
438
  >;
439
439
  };
440
440
  tools?: {
441
- [NAME in keyof InferUIMessageTools<UI_MESSAGE> & string]?: Tool<
442
- InferUIMessageTools<UI_MESSAGE>[NAME]['input'],
443
- InferUIMessageTools<UI_MESSAGE>[NAME]['output']
444
- >;
441
+ [NAME in keyof InferUIMessageTools<UI_MESSAGE> & string]?:
442
+ | Tool<
443
+ InferUIMessageTools<UI_MESSAGE>[NAME]['input'],
444
+ InferUIMessageTools<UI_MESSAGE>[NAME]['output']
445
+ >
446
+ | {
447
+ inputSchema: FlexibleSchema<
448
+ InferUIMessageTools<UI_MESSAGE>[NAME]['input']
449
+ >;
450
+ outputSchema?: FlexibleSchema<
451
+ InferUIMessageTools<UI_MESSAGE>[NAME]['output']
452
+ >;
453
+ };
445
454
  };
446
455
  };
447
456