deepline 0.3.45 → 0.3.47
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/dist/bundling-sources/sdk/src/client.ts +2 -3
- package/dist/bundling-sources/sdk/src/errors.ts +2 -2
- package/dist/bundling-sources/sdk/src/http.ts +1 -1
- package/dist/bundling-sources/sdk/src/play.ts +7 -10
- package/dist/bundling-sources/sdk/src/plays/bundle-play-file.ts +3 -3
- package/dist/bundling-sources/sdk/src/release.ts +3 -3
- package/dist/bundling-sources/sdk/src/version.ts +2 -2
- package/dist/bundling-sources/shared_libs/play-data-plane/contracts.ts +25 -0
- package/dist/bundling-sources/shared_libs/play-data-plane/index.ts +1 -0
- package/dist/bundling-sources/shared_libs/play-data-plane/sheet-contract.ts +1 -1
- package/dist/bundling-sources/shared_libs/play-runtime/app-runtime-api.ts +19 -19
- package/dist/bundling-sources/shared_libs/play-runtime/backend.ts +5 -6
- package/dist/bundling-sources/shared_libs/play-runtime/cell-staleness.ts +1 -66
- package/dist/bundling-sources/shared_libs/play-runtime/context.ts +11 -11
- package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +3 -3
- package/dist/bundling-sources/shared_libs/play-runtime/dataset-id.ts +4 -3
- package/dist/bundling-sources/shared_libs/play-runtime/durable-call-cache.ts +3 -4
- package/dist/bundling-sources/shared_libs/play-runtime/durable-receipt-execution.ts +2 -2
- package/dist/bundling-sources/shared_libs/play-runtime/email-status.ts +1 -275
- package/dist/bundling-sources/shared_libs/play-runtime/execution-ledger-store.ts +1 -1
- package/dist/bundling-sources/shared_libs/play-runtime/extractor-targets.ts +1 -106
- package/dist/bundling-sources/shared_libs/play-runtime/gateway-postgres-admission.ts +1 -2
- package/dist/bundling-sources/shared_libs/play-runtime/governor/in-memory-rate-state-backend.ts +13 -4
- package/dist/bundling-sources/shared_libs/play-runtime/live-events.ts +1 -5
- package/dist/bundling-sources/shared_libs/play-runtime/map-row-identity.ts +2 -3
- package/dist/bundling-sources/shared_libs/play-runtime/map-row-outcome.ts +2 -1
- package/dist/bundling-sources/shared_libs/play-runtime/modal-runtime-config.ts +1 -1
- package/dist/bundling-sources/shared_libs/play-runtime/output-size-limits.ts +1 -1
- package/dist/bundling-sources/shared_libs/play-runtime/projection.ts +5 -5
- package/dist/bundling-sources/shared_libs/play-runtime/protocol.ts +3 -3
- package/dist/bundling-sources/shared_libs/play-runtime/run-failure.ts +1 -1
- package/dist/bundling-sources/shared_libs/play-runtime/run-snapshot-stream.ts +1 -1
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-lifecycle.ts +4 -4
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-modal-fallback.ts +3 -3
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-payload-transport.ts +8 -8
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-session-execution.ts +1 -1
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona.ts +4 -4
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/local-process.ts +7 -7
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/modal.ts +7 -7
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/bundle.ts +13 -2
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/index.ts +2 -2
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/runner-events.ts +1 -1
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/runtime-sandbox-reconciliation.ts +1 -1
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/types.ts +2 -2
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-actions.ts +1 -1
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +6 -3
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-constants.ts +1 -1
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-constraints.ts +1 -2
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-env.ts +55 -0
- package/dist/bundling-sources/shared_libs/play-runtime/sandbox-runtime-limits.ts +1 -109
- package/dist/bundling-sources/shared_libs/play-runtime/step-program-dataset-builder.ts +1 -1
- package/dist/bundling-sources/shared_libs/play-runtime/test-runtime-seams.ts +1 -1
- package/dist/bundling-sources/shared_libs/play-runtime/tool-execute-retry-policy.ts +1 -1
- package/dist/bundling-sources/shared_libs/play-runtime/tool-execution-outcome.ts +6 -5
- package/dist/bundling-sources/shared_libs/play-runtime/tool-http-errors.ts +1 -1
- package/dist/bundling-sources/shared_libs/play-runtime/tool-result-types.ts +1 -206
- package/dist/bundling-sources/shared_libs/play-runtime/tool-result.ts +10 -7
- package/dist/bundling-sources/shared_libs/play-runtime/work-receipts.ts +1 -1
- package/dist/bundling-sources/shared_libs/plays/artifact-types.ts +8 -3
- package/dist/bundling-sources/shared_libs/plays/authoring-contract.ts +4 -4
- package/dist/bundling-sources/shared_libs/plays/bundling/index.ts +3 -6
- package/dist/bundling-sources/shared_libs/plays/cell-staleness.ts +66 -0
- package/dist/bundling-sources/shared_libs/plays/compiler-manifest.ts +1 -1
- package/dist/bundling-sources/shared_libs/plays/contracts.ts +2 -2
- package/dist/bundling-sources/shared_libs/plays/core.ts +466 -0
- package/dist/bundling-sources/shared_libs/plays/email-status.ts +287 -0
- package/dist/bundling-sources/shared_libs/plays/extractor-targets.ts +106 -0
- package/dist/bundling-sources/shared_libs/plays/row-identity.ts +1 -3
- package/dist/bundling-sources/shared_libs/plays/runtime-constraints.ts +2 -0
- package/dist/bundling-sources/shared_libs/plays/runtime-validation.ts +4 -2
- package/dist/bundling-sources/shared_libs/plays/sandbox-runtime-limits.ts +109 -0
- package/dist/bundling-sources/shared_libs/plays/tool-execution-error.ts +624 -0
- package/dist/bundling-sources/shared_libs/plays/tool-result-types.ts +206 -0
- package/dist/bundling-sources/shared_libs/security/safe-outbound-fetch.ts +1 -1
- package/dist/cli/index.js +181 -169
- package/dist/cli/index.mjs +189 -170
- package/dist/{compiler-manifest-DwYe2C2S.d.mts → compiler-manifest-BuoqasqI.d.mts} +585 -540
- package/dist/{compiler-manifest-DwYe2C2S.d.ts → compiler-manifest-BuoqasqI.d.ts} +585 -540
- package/dist/index.d.mts +9 -2
- package/dist/index.d.ts +9 -2
- package/dist/index.js +47 -40
- package/dist/index.mjs +47 -40
- package/dist/install-integrity.json +13 -3
- package/dist/plays/bundle-play-file.d.mts +4 -61
- package/dist/plays/bundle-play-file.d.ts +4 -61
- package/dist/plays/bundle-play-file.mjs +157 -155
- package/package.json +9 -6
- /package/dist/bundling-sources/shared_libs/{play-runtime → plays}/tool-response-contract.ts +0 -0
|
@@ -0,0 +1,624 @@
|
|
|
1
|
+
const DEEPLINE_ERROR_BRAND = Symbol.for('deepline.error.v1');
|
|
2
|
+
export const TOOL_EXECUTION_ERROR_BRAND = Symbol.for(
|
|
3
|
+
'deepline.tool-execution-error.v1',
|
|
4
|
+
);
|
|
5
|
+
const PROVIDER_TRANSIENT_ERROR_BRAND = Symbol.for(
|
|
6
|
+
'deepline.provider-transient-error.v1',
|
|
7
|
+
);
|
|
8
|
+
|
|
9
|
+
export const LEGACY_TOOL_EXECUTION_ERROR_SCHEMA_VERSION = 0 as const;
|
|
10
|
+
export const TOOL_EXECUTION_ERROR_SCHEMA_VERSION = 1 as const;
|
|
11
|
+
export const SUPPORTED_TOOL_EXECUTION_ERROR_SCHEMA_VERSIONS = [
|
|
12
|
+
LEGACY_TOOL_EXECUTION_ERROR_SCHEMA_VERSION,
|
|
13
|
+
TOOL_EXECUTION_ERROR_SCHEMA_VERSION,
|
|
14
|
+
] as const;
|
|
15
|
+
export type ToolExecutionErrorSchemaVersion =
|
|
16
|
+
(typeof SUPPORTED_TOOL_EXECUTION_ERROR_SCHEMA_VERSIONS)[number];
|
|
17
|
+
export const TOOL_EXECUTION_ERROR_SCHEMA_HEADER =
|
|
18
|
+
'x-deepline-tool-error-schema';
|
|
19
|
+
|
|
20
|
+
const MAX_IDENTIFIER_LENGTH = 200;
|
|
21
|
+
const MAX_CODE_LENGTH = 160;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* The boundary responsible for a failed tool call.
|
|
25
|
+
*
|
|
26
|
+
* Use `provider` to distinguish a provider answer from caller input and
|
|
27
|
+
* Deepline infrastructure. `unknown` fails closed and must not trigger a
|
|
28
|
+
* waterfall fallback.
|
|
29
|
+
*
|
|
30
|
+
* @sdkReference errors 020
|
|
31
|
+
*/
|
|
32
|
+
export type ToolExecutionErrorOrigin =
|
|
33
|
+
| 'caller'
|
|
34
|
+
| 'provider'
|
|
35
|
+
| 'deepline'
|
|
36
|
+
| 'unknown';
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* The stable reason family for a failed tool call.
|
|
40
|
+
*
|
|
41
|
+
* Branch on this field only after narrowing to `ToolExecutionError`. Catch
|
|
42
|
+
* `ProviderTransientError` when the policy is simply “try the next read
|
|
43
|
+
* provider”; it is the safer and shorter waterfall contract.
|
|
44
|
+
*
|
|
45
|
+
* @sdkReference errors 030
|
|
46
|
+
*/
|
|
47
|
+
export type ToolExecutionErrorCategory =
|
|
48
|
+
| 'validation'
|
|
49
|
+
| 'authentication'
|
|
50
|
+
| 'authorization'
|
|
51
|
+
| 'rate_limit'
|
|
52
|
+
| 'network'
|
|
53
|
+
| 'upstream'
|
|
54
|
+
| 'billing'
|
|
55
|
+
| 'conflict'
|
|
56
|
+
| 'internal'
|
|
57
|
+
| 'unknown';
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* The transport failure observed when `category` is `network`.
|
|
61
|
+
*
|
|
62
|
+
* This is `null` for failures that are not network failures.
|
|
63
|
+
*
|
|
64
|
+
* @sdkReference errors 040
|
|
65
|
+
*/
|
|
66
|
+
export type ToolExecutionNetworkKind =
|
|
67
|
+
| 'timeout'
|
|
68
|
+
| 'dns'
|
|
69
|
+
| 'connect'
|
|
70
|
+
| 'reset'
|
|
71
|
+
| 'unavailable'
|
|
72
|
+
| 'unknown';
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* The request boundary on which a network failure occurred.
|
|
76
|
+
*
|
|
77
|
+
* `deepline_to_provider` is provider-side. Client and runtime scopes are
|
|
78
|
+
* Deepline transport failures and never qualify as provider fallthrough.
|
|
79
|
+
*
|
|
80
|
+
* @sdkReference errors 050
|
|
81
|
+
*/
|
|
82
|
+
export type ToolExecutionNetworkScope =
|
|
83
|
+
| 'client_to_deepline'
|
|
84
|
+
| 'runtime_to_deepline'
|
|
85
|
+
| 'deepline_to_provider';
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Portable version-1 `tool_error` payload.
|
|
89
|
+
*
|
|
90
|
+
* This allowlisted shape crosses the API, runtime, and SDK boundaries.
|
|
91
|
+
* `message` remains on the Error object and is deliberately not a policy
|
|
92
|
+
* field.
|
|
93
|
+
*
|
|
94
|
+
* @sdkReference errors 064
|
|
95
|
+
*/
|
|
96
|
+
export type ToolExecutionFailureV1 = {
|
|
97
|
+
/** Payload version. */
|
|
98
|
+
schemaVersion: typeof TOOL_EXECUTION_ERROR_SCHEMA_VERSION;
|
|
99
|
+
/** Public tool id passed to `tools.execute`. */
|
|
100
|
+
toolId: string;
|
|
101
|
+
/** Provider responsible for the operation, or `null`. */
|
|
102
|
+
provider: string | null;
|
|
103
|
+
/** Provider operation name, or `null`. */
|
|
104
|
+
operation: string | null;
|
|
105
|
+
/** Stable machine-readable failure code, or `null`. */
|
|
106
|
+
code: string | null;
|
|
107
|
+
/** Boundary responsible for the failure. */
|
|
108
|
+
origin: ToolExecutionErrorOrigin;
|
|
109
|
+
/** Stable reason family. */
|
|
110
|
+
category: ToolExecutionErrorCategory;
|
|
111
|
+
/** Whether repeating the same semantic call is delivery-safe. */
|
|
112
|
+
retryable: boolean;
|
|
113
|
+
/** HTTP status when one exists, or `null`. */
|
|
114
|
+
statusCode: number | null;
|
|
115
|
+
/** Provider or Deepline request id, or `null`. */
|
|
116
|
+
requestId: string | null;
|
|
117
|
+
/** Suggested same-call retry delay in milliseconds, or `null`. */
|
|
118
|
+
retryAfterMs: number | null;
|
|
119
|
+
/** Network failure kind, or `null`. */
|
|
120
|
+
networkKind: ToolExecutionNetworkKind | null;
|
|
121
|
+
/** Network boundary that failed, or `null`. */
|
|
122
|
+
networkScope: ToolExecutionNetworkScope | null;
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Constructor input for a structured tool failure.
|
|
127
|
+
*
|
|
128
|
+
* Deepline creates these values while decoding the versioned wire payload.
|
|
129
|
+
* Customer code normally reads `ToolExecutionError` fields instead of
|
|
130
|
+
* constructing an error.
|
|
131
|
+
*
|
|
132
|
+
* @sdkReference errors 065
|
|
133
|
+
*/
|
|
134
|
+
export type ToolExecutionErrorOptions = Omit<
|
|
135
|
+
ToolExecutionFailureV1,
|
|
136
|
+
'schemaVersion'
|
|
137
|
+
> & {
|
|
138
|
+
/**
|
|
139
|
+
* Local diagnostic context inherited from DeeplineError. This is not part of
|
|
140
|
+
* the portable failure payload and is intentionally omitted by serialization.
|
|
141
|
+
*/
|
|
142
|
+
details?: Record<string, unknown>;
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Provider-owned failure categories that may fall through to another read
|
|
147
|
+
* provider.
|
|
148
|
+
*
|
|
149
|
+
* @sdkReference errors 060
|
|
150
|
+
*/
|
|
151
|
+
export type ProviderTransientErrorCategory =
|
|
152
|
+
| 'rate_limit'
|
|
153
|
+
| 'network'
|
|
154
|
+
| 'upstream';
|
|
155
|
+
|
|
156
|
+
function nativeInstanceOf(constructor: object, value: unknown): boolean {
|
|
157
|
+
return Reflect.apply(Function.prototype[Symbol.hasInstance], constructor, [
|
|
158
|
+
value,
|
|
159
|
+
]) as boolean;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function hasBrand(value: unknown, brand: symbol): boolean {
|
|
163
|
+
return (
|
|
164
|
+
typeof value === 'object' &&
|
|
165
|
+
value !== null &&
|
|
166
|
+
(value as Record<symbol, unknown>)[brand] === true
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function applyBrand(value: object, brand: symbol): void {
|
|
171
|
+
if (hasBrand(value, brand)) return;
|
|
172
|
+
Object.defineProperty(value, brand, {
|
|
173
|
+
configurable: false,
|
|
174
|
+
enumerable: false,
|
|
175
|
+
writable: false,
|
|
176
|
+
value: true,
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Base error class shared by the SDK and play runtime.
|
|
182
|
+
*
|
|
183
|
+
* The global brand preserves `instanceof DeeplineError` when a bundled play
|
|
184
|
+
* and the runtime load separate physical copies of this module.
|
|
185
|
+
*
|
|
186
|
+
* @sdkReference errors 010
|
|
187
|
+
*/
|
|
188
|
+
export class DeeplineError extends Error {
|
|
189
|
+
/** HTTP status when the failure crossed an HTTP boundary. */
|
|
190
|
+
statusCode?: number;
|
|
191
|
+
/** Stable machine-readable error code when one exists. */
|
|
192
|
+
code?: string;
|
|
193
|
+
/** Local diagnostic context; not a portable error contract. */
|
|
194
|
+
details?: Record<string, unknown>;
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Construct a Deepline error.
|
|
198
|
+
*
|
|
199
|
+
* SDK and runtime code construct these errors. Application and Play code
|
|
200
|
+
* normally catches the public subclasses instead.
|
|
201
|
+
*
|
|
202
|
+
* @param message Human-readable failure summary.
|
|
203
|
+
* @param statusCode HTTP status when one exists.
|
|
204
|
+
* @param code Stable machine-readable code when one exists.
|
|
205
|
+
* @param details Local diagnostic context; never a portable error contract.
|
|
206
|
+
*/
|
|
207
|
+
constructor(
|
|
208
|
+
message: string,
|
|
209
|
+
statusCode?: number,
|
|
210
|
+
code?: string,
|
|
211
|
+
details?: Record<string, unknown>,
|
|
212
|
+
) {
|
|
213
|
+
super(message);
|
|
214
|
+
this.name = 'DeeplineError';
|
|
215
|
+
this.statusCode = statusCode;
|
|
216
|
+
this.code = code;
|
|
217
|
+
this.details = details;
|
|
218
|
+
applyBrand(this, DEEPLINE_ERROR_BRAND);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
static [Symbol.hasInstance](value: unknown): boolean {
|
|
222
|
+
// Subclasses inherit static methods. Delegate subclass checks to the native
|
|
223
|
+
// prototype algorithm so AuthError never accidentally matches ConfigError.
|
|
224
|
+
if (this !== DeeplineError) return nativeInstanceOf(this, value);
|
|
225
|
+
return hasBrand(value, DEEPLINE_ERROR_BRAND);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* A failed `tools.execute` call with stable, allowlisted provenance.
|
|
231
|
+
*
|
|
232
|
+
* `retryable` means Deepline's delivery/idempotency contract says it is safe
|
|
233
|
+
* to repeat the same semantic call. It does not describe durable receipt
|
|
234
|
+
* repairability and does not make arbitrary side-effecting fallbacks safe.
|
|
235
|
+
*
|
|
236
|
+
* In a Play, catch `ProviderTransientError` to continue a read waterfall and
|
|
237
|
+
* let every other `ToolExecutionError` remain loud. In an SDK client, catch
|
|
238
|
+
* this base class when you need structured diagnostics for every tool failure.
|
|
239
|
+
*
|
|
240
|
+
* @sdkReference errors 070
|
|
241
|
+
*/
|
|
242
|
+
export class ToolExecutionError extends DeeplineError {
|
|
243
|
+
/** Public tool id passed to `tools.execute`. */
|
|
244
|
+
readonly toolId: string;
|
|
245
|
+
/** Provider responsible for the operation, or `null` when unattributed. */
|
|
246
|
+
readonly provider: string | null;
|
|
247
|
+
/** Provider operation name, or `null` when unavailable. */
|
|
248
|
+
readonly operation: string | null;
|
|
249
|
+
/** Boundary responsible for the failure. */
|
|
250
|
+
readonly origin: ToolExecutionErrorOrigin;
|
|
251
|
+
/** Stable reason family for policy and diagnostics. */
|
|
252
|
+
readonly category: ToolExecutionErrorCategory;
|
|
253
|
+
/**
|
|
254
|
+
* Whether repeating the same semantic call is delivery-safe.
|
|
255
|
+
*
|
|
256
|
+
* This does not mean the error may be ignored. Waterfall fallthrough is
|
|
257
|
+
* represented by `ProviderTransientError`.
|
|
258
|
+
*/
|
|
259
|
+
readonly retryable: boolean;
|
|
260
|
+
/** Provider or Deepline request id, or `null` when unavailable. */
|
|
261
|
+
readonly requestId: string | null;
|
|
262
|
+
/** Suggested same-call retry delay in milliseconds, or `null`. */
|
|
263
|
+
readonly retryAfterMs: number | null;
|
|
264
|
+
/** Network failure kind, or `null` for non-network failures. */
|
|
265
|
+
readonly networkKind: ToolExecutionNetworkKind | null;
|
|
266
|
+
/** Network boundary that failed, or `null` for non-network failures. */
|
|
267
|
+
readonly networkScope: ToolExecutionNetworkScope | null;
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* Construct a structured tool error.
|
|
271
|
+
*
|
|
272
|
+
* Deepline constructs this from the versioned `tool_error` payload.
|
|
273
|
+
* Application and Play code should catch it rather than create it.
|
|
274
|
+
*/
|
|
275
|
+
constructor(message: string, options: ToolExecutionErrorOptions) {
|
|
276
|
+
super(
|
|
277
|
+
message,
|
|
278
|
+
options.statusCode ?? undefined,
|
|
279
|
+
options.code ?? undefined,
|
|
280
|
+
options.details,
|
|
281
|
+
);
|
|
282
|
+
this.name = 'ToolExecutionError';
|
|
283
|
+
this.toolId = options.toolId;
|
|
284
|
+
this.provider = options.provider;
|
|
285
|
+
this.operation = options.operation;
|
|
286
|
+
this.origin = options.origin;
|
|
287
|
+
this.category = options.category;
|
|
288
|
+
this.retryable = options.retryable;
|
|
289
|
+
this.requestId = options.requestId;
|
|
290
|
+
this.retryAfterMs = options.retryAfterMs;
|
|
291
|
+
this.networkKind = options.networkKind;
|
|
292
|
+
this.networkScope = options.networkScope;
|
|
293
|
+
applyBrand(this, TOOL_EXECUTION_ERROR_BRAND);
|
|
294
|
+
if (isProviderTransientFailure(options)) {
|
|
295
|
+
applyBrand(this, PROVIDER_TRANSIENT_ERROR_BRAND);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
static [Symbol.hasInstance](value: unknown): boolean {
|
|
300
|
+
if (this !== ToolExecutionError) return nativeInstanceOf(this, value);
|
|
301
|
+
return hasBrand(value, TOOL_EXECUTION_ERROR_BRAND);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* Brands a compatibility subclass (notably SDK ToolRateLimitError) as a tool
|
|
307
|
+
* failure without changing its existing prototype chain.
|
|
308
|
+
*/
|
|
309
|
+
export function brandAsToolExecutionError(value: object): void {
|
|
310
|
+
applyBrand(value, TOOL_EXECUTION_ERROR_BRAND);
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
export function isProviderTransientFailure(input: {
|
|
314
|
+
origin: ToolExecutionErrorOrigin;
|
|
315
|
+
category: ToolExecutionErrorCategory;
|
|
316
|
+
retryable: boolean;
|
|
317
|
+
}): input is {
|
|
318
|
+
origin: 'provider';
|
|
319
|
+
category: ProviderTransientErrorCategory;
|
|
320
|
+
retryable: boolean;
|
|
321
|
+
} {
|
|
322
|
+
return (
|
|
323
|
+
input.origin === 'provider' &&
|
|
324
|
+
(input.category === 'rate_limit' ||
|
|
325
|
+
input.category === 'network' ||
|
|
326
|
+
input.category === 'upstream')
|
|
327
|
+
);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* A provider-owned transient failure that is safe to handle as an empty
|
|
332
|
+
* waterfall leg. Validation, auth, billing, Deepline, and unknown failures
|
|
333
|
+
* never satisfy this type.
|
|
334
|
+
*
|
|
335
|
+
* `retryable` remains independent: it says whether the same semantic call may
|
|
336
|
+
* be repeated safely. Falling through to a different read provider depends on
|
|
337
|
+
* this class, not on `retryable`.
|
|
338
|
+
*
|
|
339
|
+
* @sdkReference errors 080
|
|
340
|
+
*/
|
|
341
|
+
export class ProviderTransientError extends ToolExecutionError {
|
|
342
|
+
/** Provider attribution is guaranteed for this subtype. */
|
|
343
|
+
override readonly origin = 'provider' as const;
|
|
344
|
+
/** Provider failure category that made this error eligible for fallthrough. */
|
|
345
|
+
declare readonly category: ProviderTransientErrorCategory;
|
|
346
|
+
|
|
347
|
+
/** Constructed by Deepline when a provider-owned transient failure arrives. */
|
|
348
|
+
constructor(
|
|
349
|
+
message: string,
|
|
350
|
+
options: Omit<ToolExecutionErrorOptions, 'origin' | 'category'> & {
|
|
351
|
+
category: ProviderTransientErrorCategory;
|
|
352
|
+
},
|
|
353
|
+
) {
|
|
354
|
+
super(message, {
|
|
355
|
+
...options,
|
|
356
|
+
origin: 'provider',
|
|
357
|
+
category: options.category,
|
|
358
|
+
});
|
|
359
|
+
this.name = 'ProviderTransientError';
|
|
360
|
+
this.category = options.category;
|
|
361
|
+
applyBrand(this, PROVIDER_TRANSIENT_ERROR_BRAND);
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
static [Symbol.hasInstance](value: unknown): boolean {
|
|
365
|
+
if (this !== ProviderTransientError) return nativeInstanceOf(this, value);
|
|
366
|
+
return hasBrand(value, PROVIDER_TRANSIENT_ERROR_BRAND);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/** Why a provider cannot serve the current read request. */
|
|
371
|
+
export type ProviderUnavailableReason =
|
|
372
|
+
| ProviderTransientErrorCategory
|
|
373
|
+
| 'account_capacity'
|
|
374
|
+
| 'credentials_missing';
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* A provider failure that permits a read waterfall to try its next provider.
|
|
378
|
+
* A missing provider connection is included because another provider may still
|
|
379
|
+
* serve the read. Invalid credentials, caller input, and Deepline billing
|
|
380
|
+
* failures remain loud.
|
|
381
|
+
*/
|
|
382
|
+
export type ProviderUnavailableError =
|
|
383
|
+
| ProviderTransientError
|
|
384
|
+
| (ToolExecutionError & {
|
|
385
|
+
readonly origin: 'provider';
|
|
386
|
+
readonly code: 'PROVIDER_ACCOUNT_CAPACITY';
|
|
387
|
+
})
|
|
388
|
+
| (ToolExecutionError & {
|
|
389
|
+
readonly origin: 'caller';
|
|
390
|
+
readonly code: 'INTEGRATION_CREDENTIALS_MISSING';
|
|
391
|
+
});
|
|
392
|
+
|
|
393
|
+
/**
|
|
394
|
+
* Return the provider-specific reason a read cannot run right now.
|
|
395
|
+
*
|
|
396
|
+
* `null` means this error must stay loud: it is caller input, an invalid
|
|
397
|
+
* customer credential, Deepline billing, or an internal failure. A missing
|
|
398
|
+
* provider connection is different: an explicit read waterfall may continue
|
|
399
|
+
* to a configured fallback and record the unavailable leg.
|
|
400
|
+
*/
|
|
401
|
+
export function getProviderUnavailableReason(
|
|
402
|
+
error: unknown,
|
|
403
|
+
): ProviderUnavailableReason | null {
|
|
404
|
+
if (error instanceof ProviderTransientError) return error.category;
|
|
405
|
+
if (
|
|
406
|
+
error instanceof ToolExecutionError &&
|
|
407
|
+
error.origin === 'provider' &&
|
|
408
|
+
error.code === 'PROVIDER_ACCOUNT_CAPACITY'
|
|
409
|
+
) {
|
|
410
|
+
return 'account_capacity';
|
|
411
|
+
}
|
|
412
|
+
if (
|
|
413
|
+
error instanceof ToolExecutionError &&
|
|
414
|
+
error.origin === 'caller' &&
|
|
415
|
+
error.code === 'INTEGRATION_CREDENTIALS_MISSING'
|
|
416
|
+
) {
|
|
417
|
+
return 'credentials_missing';
|
|
418
|
+
}
|
|
419
|
+
return null;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
/**
|
|
423
|
+
* Whether a provider cannot serve this read right now.
|
|
424
|
+
*
|
|
425
|
+
* Use this in an explicit `catch` to advance a read-only waterfall. For
|
|
426
|
+
* diagnostics, use `getProviderUnavailableReason(error)`.
|
|
427
|
+
*/
|
|
428
|
+
export function isProviderUnavailable(
|
|
429
|
+
error: unknown,
|
|
430
|
+
): error is ProviderUnavailableError {
|
|
431
|
+
return getProviderUnavailableReason(error) !== null;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
/** @deprecated Use isProviderUnavailable. */
|
|
435
|
+
export const isProviderWaterfallUnavailableError = isProviderUnavailable;
|
|
436
|
+
|
|
437
|
+
/** Brand an internal compatibility error after its normalized fields exist. */
|
|
438
|
+
export function brandAsProviderTransientError(value: object): void {
|
|
439
|
+
applyBrand(value, PROVIDER_TRANSIENT_ERROR_BRAND);
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
function boundedString(
|
|
443
|
+
value: unknown,
|
|
444
|
+
maxLength = MAX_IDENTIFIER_LENGTH,
|
|
445
|
+
): string | null {
|
|
446
|
+
if (typeof value !== 'string') return null;
|
|
447
|
+
const normalized = value.trim();
|
|
448
|
+
return normalized ? normalized.slice(0, maxLength) : null;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
function finiteNonNegativeInteger(value: unknown): number | null {
|
|
452
|
+
return typeof value === 'number' &&
|
|
453
|
+
Number.isFinite(value) &&
|
|
454
|
+
value >= 0 &&
|
|
455
|
+
Number.isInteger(value)
|
|
456
|
+
? value
|
|
457
|
+
: null;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
export function normalizeToolExecutionOrigin(
|
|
461
|
+
value: unknown,
|
|
462
|
+
input?: { provider?: string | null; operation?: string | null },
|
|
463
|
+
): ToolExecutionErrorOrigin {
|
|
464
|
+
const normalized = boundedString(value)?.toLowerCase();
|
|
465
|
+
if (normalized === 'caller') return 'caller';
|
|
466
|
+
if (normalized === 'provider' || normalized === 'provider_network') {
|
|
467
|
+
return 'provider';
|
|
468
|
+
}
|
|
469
|
+
// Older integration adapters use "upstream" for a provider-owned failure.
|
|
470
|
+
// Only accept that alias when the execution boundary identifies the provider
|
|
471
|
+
// action; an unscoped upstream error fails closed.
|
|
472
|
+
if (
|
|
473
|
+
normalized === 'upstream' &&
|
|
474
|
+
boundedString(input?.provider) &&
|
|
475
|
+
boundedString(input?.operation)
|
|
476
|
+
) {
|
|
477
|
+
return 'provider';
|
|
478
|
+
}
|
|
479
|
+
if (
|
|
480
|
+
normalized === 'deepline' ||
|
|
481
|
+
normalized === 'deepline_billing' ||
|
|
482
|
+
normalized === 'deepline_rate_limit' ||
|
|
483
|
+
normalized === 'internal' ||
|
|
484
|
+
normalized === 'server'
|
|
485
|
+
) {
|
|
486
|
+
return 'deepline';
|
|
487
|
+
}
|
|
488
|
+
if (normalized === 'provider_account') return 'provider';
|
|
489
|
+
return 'unknown';
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
export function normalizeToolExecutionCategory(
|
|
493
|
+
value: unknown,
|
|
494
|
+
): ToolExecutionErrorCategory {
|
|
495
|
+
switch (boundedString(value)?.toLowerCase()) {
|
|
496
|
+
case 'validation':
|
|
497
|
+
case 'authorization':
|
|
498
|
+
case 'rate_limit':
|
|
499
|
+
case 'network':
|
|
500
|
+
case 'upstream':
|
|
501
|
+
case 'billing':
|
|
502
|
+
case 'conflict':
|
|
503
|
+
case 'internal':
|
|
504
|
+
return boundedString(value)!.toLowerCase() as ToolExecutionErrorCategory;
|
|
505
|
+
case 'authentication':
|
|
506
|
+
case 'provider_auth':
|
|
507
|
+
case 'provider_account':
|
|
508
|
+
return 'authentication';
|
|
509
|
+
case 'execution':
|
|
510
|
+
case 'parse':
|
|
511
|
+
case 'stub':
|
|
512
|
+
case 'internal_native_search_performance':
|
|
513
|
+
return 'internal';
|
|
514
|
+
default:
|
|
515
|
+
return 'unknown';
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
function normalizeNetworkKind(value: unknown): ToolExecutionNetworkKind | null {
|
|
520
|
+
switch (boundedString(value)?.toLowerCase()) {
|
|
521
|
+
case 'timeout':
|
|
522
|
+
case 'dns':
|
|
523
|
+
case 'connect':
|
|
524
|
+
case 'reset':
|
|
525
|
+
case 'unavailable':
|
|
526
|
+
case 'unknown':
|
|
527
|
+
return boundedString(value)!.toLowerCase() as ToolExecutionNetworkKind;
|
|
528
|
+
default:
|
|
529
|
+
return null;
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
function normalizeNetworkScope(
|
|
534
|
+
value: unknown,
|
|
535
|
+
): ToolExecutionNetworkScope | null {
|
|
536
|
+
switch (boundedString(value)?.toLowerCase()) {
|
|
537
|
+
case 'client_to_deepline':
|
|
538
|
+
case 'runtime_to_deepline':
|
|
539
|
+
case 'deepline_to_provider':
|
|
540
|
+
return boundedString(value)!.toLowerCase() as ToolExecutionNetworkScope;
|
|
541
|
+
default:
|
|
542
|
+
return null;
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
547
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
export function normalizeToolExecutionFailure(
|
|
551
|
+
value: unknown,
|
|
552
|
+
): ToolExecutionFailureV1 | null {
|
|
553
|
+
if (
|
|
554
|
+
!isRecord(value) ||
|
|
555
|
+
value.schemaVersion !== TOOL_EXECUTION_ERROR_SCHEMA_VERSION
|
|
556
|
+
) {
|
|
557
|
+
return null;
|
|
558
|
+
}
|
|
559
|
+
const toolId = boundedString(value.toolId);
|
|
560
|
+
if (!toolId) return null;
|
|
561
|
+
const provider = boundedString(value.provider);
|
|
562
|
+
const operation = boundedString(value.operation);
|
|
563
|
+
const origin = normalizeToolExecutionOrigin(value.origin, {
|
|
564
|
+
provider,
|
|
565
|
+
operation,
|
|
566
|
+
});
|
|
567
|
+
const category = normalizeToolExecutionCategory(value.category);
|
|
568
|
+
const trustworthy =
|
|
569
|
+
origin !== 'unknown' &&
|
|
570
|
+
category !== 'unknown' &&
|
|
571
|
+
typeof value.retryable === 'boolean';
|
|
572
|
+
return {
|
|
573
|
+
schemaVersion: TOOL_EXECUTION_ERROR_SCHEMA_VERSION,
|
|
574
|
+
toolId,
|
|
575
|
+
provider,
|
|
576
|
+
operation,
|
|
577
|
+
code: boundedString(value.code, MAX_CODE_LENGTH),
|
|
578
|
+
origin,
|
|
579
|
+
category,
|
|
580
|
+
retryable: trustworthy ? value.retryable === true : false,
|
|
581
|
+
statusCode: finiteNonNegativeInteger(value.statusCode),
|
|
582
|
+
requestId: boundedString(value.requestId),
|
|
583
|
+
retryAfterMs: finiteNonNegativeInteger(value.retryAfterMs),
|
|
584
|
+
networkKind: normalizeNetworkKind(value.networkKind),
|
|
585
|
+
networkScope: normalizeNetworkScope(value.networkScope),
|
|
586
|
+
};
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
export function serializeToolExecutionFailure(
|
|
590
|
+
error: unknown,
|
|
591
|
+
): ToolExecutionFailureV1 | null {
|
|
592
|
+
if (!(error instanceof ToolExecutionError)) return null;
|
|
593
|
+
return normalizeToolExecutionFailure({
|
|
594
|
+
schemaVersion: TOOL_EXECUTION_ERROR_SCHEMA_VERSION,
|
|
595
|
+
toolId: error.toolId,
|
|
596
|
+
provider: error.provider,
|
|
597
|
+
operation: error.operation,
|
|
598
|
+
code: error.code ?? null,
|
|
599
|
+
origin: error.origin,
|
|
600
|
+
category: error.category,
|
|
601
|
+
retryable: error.retryable,
|
|
602
|
+
statusCode: error.statusCode ?? null,
|
|
603
|
+
requestId: error.requestId,
|
|
604
|
+
retryAfterMs: error.retryAfterMs,
|
|
605
|
+
networkKind: error.networkKind,
|
|
606
|
+
networkScope: error.networkScope,
|
|
607
|
+
});
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
export function deserializeToolExecutionFailure(
|
|
611
|
+
message: string,
|
|
612
|
+
value: unknown,
|
|
613
|
+
acceptedSchemaVersion: ToolExecutionErrorSchemaVersion,
|
|
614
|
+
): ToolExecutionError | null {
|
|
615
|
+
if (acceptedSchemaVersion === LEGACY_TOOL_EXECUTION_ERROR_SCHEMA_VERSION) {
|
|
616
|
+
return null;
|
|
617
|
+
}
|
|
618
|
+
const failure = normalizeToolExecutionFailure(value);
|
|
619
|
+
if (!failure) return null;
|
|
620
|
+
if (isProviderTransientFailure(failure)) {
|
|
621
|
+
return new ProviderTransientError(message, failure);
|
|
622
|
+
}
|
|
623
|
+
return new ToolExecutionError(message, failure);
|
|
624
|
+
}
|