@ai-sdk/provider-utils 5.0.12 → 5.0.14

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-sdk/provider-utils",
3
- "version": "5.0.12",
3
+ "version": "5.0.14",
4
4
  "type": "module",
5
5
  "license": "Apache-2.0",
6
6
  "sideEffects": false,
@@ -35,7 +35,7 @@
35
35
  "@standard-schema/spec": "^1.1.0",
36
36
  "@workflow/serde": "4.1.0",
37
37
  "eventsource-parser": "^3.0.8",
38
- "@ai-sdk/provider": "4.0.3"
38
+ "@ai-sdk/provider": "4.0.4"
39
39
  },
40
40
  "devDependencies": {
41
41
  "@types/node": "22.19.19",
@@ -46,7 +46,11 @@ export function connectToWebSocket({
46
46
  /** Constructor throws and message decoding/processing failures. */
47
47
  onProcessingError: (error: unknown) => void;
48
48
  onSocketError?: () => void;
49
- onClose?: () => void;
49
+ /**
50
+ * Receives the close code and reason when the transport provides them
51
+ * (native `CloseEvent` / `ws` close event).
52
+ */
53
+ onClose?: (info: { code?: number; reason?: string }) => void;
50
54
  /** Also called (without opening a socket) when the signal is already aborted. */
51
55
  onAbort?: (reason: unknown) => void;
52
56
  }): WebSocketConnection {
@@ -108,8 +112,20 @@ export function connectToWebSocket({
108
112
  socket.onerror = () => {
109
113
  tail = tail.then(() => onSocketError?.()).catch(onProcessingError);
110
114
  };
111
- socket.onclose = () => {
112
- tail = tail.then(() => onClose?.()).catch(onProcessingError);
115
+ socket.onclose = event => {
116
+ // Extract close diagnostics when the transport provides them (native
117
+ // `CloseEvent` and `ws` both carry `code` and `reason`).
118
+ const closeEvent = event as
119
+ | { code?: unknown; reason?: unknown }
120
+ | null
121
+ | undefined;
122
+ const code =
123
+ typeof closeEvent?.code === 'number' ? closeEvent.code : undefined;
124
+ const reason =
125
+ typeof closeEvent?.reason === 'string' ? closeEvent.reason : undefined;
126
+ tail = tail
127
+ .then(() => onClose?.({ code, reason }))
128
+ .catch(onProcessingError);
113
129
  };
114
130
 
115
131
  return { socket, close };
package/src/index.ts CHANGED
@@ -88,6 +88,7 @@ export {
88
88
  type ValidationResult,
89
89
  } from './schema';
90
90
  export { serializeModelOptions } from './serialize-model-options';
91
+ export { SerializationError } from './serialization-error';
91
92
  export { secureJsonParse } from './secure-json-parse';
92
93
  export {
93
94
  StreamingToolCallTracker,
@@ -0,0 +1,23 @@
1
+ import { AISDKError } from '@ai-sdk/provider';
2
+
3
+ const name = 'AI_SerializationError';
4
+ const marker = `vercel.ai.error.${name}`;
5
+ const symbol = Symbol.for(marker);
6
+
7
+ export class SerializationError extends AISDKError {
8
+ private readonly [symbol] = true; // used in isInstance
9
+
10
+ constructor({
11
+ message = 'Failed to serialize value.',
12
+ cause,
13
+ }: {
14
+ message?: string;
15
+ cause?: unknown;
16
+ } = {}) {
17
+ super({ name, message, cause });
18
+ }
19
+
20
+ static isInstance(error: unknown): error is SerializationError {
21
+ return AISDKError.hasMarker(error, marker);
22
+ }
23
+ }
@@ -1,6 +1,7 @@
1
1
  import type { JSONObject } from '@ai-sdk/provider';
2
2
  import { isJSONSerializable } from './is-json-serializable';
3
3
  import type { Resolvable } from './resolve';
4
+ import { SerializationError } from './serialization-error';
4
5
 
5
6
  /**
6
7
  * Serializes a model instance for workflow step boundaries.
@@ -53,10 +54,10 @@ function resolveSync<T>(value: Resolvable<T>): T {
53
54
  next = (value as () => unknown)();
54
55
  }
55
56
 
56
- // the serialization for workflows currently only supports synchronous values
57
- // TODO introduce SerializationError
58
57
  if (next instanceof Promise) {
59
- throw new Error('Promise returned from resolveSync');
58
+ throw new SerializationError({
59
+ message: 'Cannot serialize asynchronous model options.',
60
+ });
60
61
  }
61
62
 
62
63
  return next as T;