@pipelex/sdk 0.52.0 → 0.53.0

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.
Files changed (88) hide show
  1. package/README.md +17 -17
  2. package/dist/answer-reading.d.ts +70 -0
  3. package/dist/answer-reading.js +106 -0
  4. package/dist/answer-reading.js.map +1 -0
  5. package/dist/artifacts.js +45 -32
  6. package/dist/artifacts.js.map +1 -1
  7. package/dist/cli/present.d.ts +11 -14
  8. package/dist/cli/present.js +41 -37
  9. package/dist/cli/present.js.map +1 -1
  10. package/dist/cli/run.js +8 -7
  11. package/dist/cli/run.js.map +1 -1
  12. package/dist/cli/script.d.ts +1 -1
  13. package/dist/cli/source.js +2 -2
  14. package/dist/cli/source.js.map +1 -1
  15. package/dist/client.d.ts +248 -218
  16. package/dist/client.js +538 -477
  17. package/dist/client.js.map +1 -1
  18. package/dist/codegen-check.d.ts +21 -15
  19. package/dist/codegen-check.js +54 -27
  20. package/dist/codegen-check.js.map +1 -1
  21. package/dist/errors.d.ts +298 -455
  22. package/dist/errors.js +426 -534
  23. package/dist/errors.js.map +1 -1
  24. package/dist/exact-json.d.ts +8 -12
  25. package/dist/exact-json.js +19 -12
  26. package/dist/exact-json.js.map +1 -1
  27. package/dist/hooks/check-core.d.ts +12 -7
  28. package/dist/hooks/check-core.js +20 -14
  29. package/dist/hooks/check-core.js.map +1 -1
  30. package/dist/hooks/validate-stage.js +12 -3
  31. package/dist/hooks/validate-stage.js.map +1 -1
  32. package/dist/index.d.ts +4 -5
  33. package/dist/index.js +7 -6
  34. package/dist/index.js.map +1 -1
  35. package/dist/method-selector.js +7 -5
  36. package/dist/method-selector.js.map +1 -1
  37. package/dist/method-trees.d.ts +6 -7
  38. package/dist/method-trees.js +31 -37
  39. package/dist/method-trees.js.map +1 -1
  40. package/dist/models.d.ts +33 -210
  41. package/dist/models.js +2 -1
  42. package/dist/models.js.map +1 -1
  43. package/dist/prepare-inputs.d.ts +2 -2
  44. package/dist/prepare-inputs.js +51 -54
  45. package/dist/prepare-inputs.js.map +1 -1
  46. package/dist/problem-items.d.ts +19 -0
  47. package/dist/problem-items.js +52 -0
  48. package/dist/problem-items.js.map +1 -0
  49. package/dist/product-models.d.ts +23 -21
  50. package/dist/records.d.ts +12 -0
  51. package/dist/records.js +23 -0
  52. package/dist/records.js.map +1 -0
  53. package/dist/runs.d.ts +49 -38
  54. package/dist/runs.js +45 -19
  55. package/dist/runs.js.map +1 -1
  56. package/dist/transport-reading.d.ts +18 -0
  57. package/dist/{run-may-have-started.js → transport-reading.js} +15 -44
  58. package/dist/transport-reading.js.map +1 -0
  59. package/dist/upload-grant.d.ts +9 -6
  60. package/dist/upload-grant.js +42 -29
  61. package/dist/upload-grant.js.map +1 -1
  62. package/dist/upload.js +53 -33
  63. package/dist/upload.js.map +1 -1
  64. package/dist/version.d.ts +1 -1
  65. package/dist/version.js +1 -1
  66. package/docs/architecture.md +19 -19
  67. package/docs/artifact-download.md +6 -6
  68. package/docs/cli.md +1 -1
  69. package/docs/crate-routes.md +13 -14
  70. package/docs/errors.md +154 -267
  71. package/docs/exact-integers.md +1 -1
  72. package/docs/files.md +13 -13
  73. package/docs/hook-bundle.md +15 -1
  74. package/docs/input-preparation.md +14 -14
  75. package/docs/method-copy.md +24 -24
  76. package/docs/method-examples.md +13 -14
  77. package/docs/method-trees.md +27 -28
  78. package/docs/organization-branding.md +14 -16
  79. package/docs/run-results.md +8 -8
  80. package/package.json +1 -1
  81. package/dist/error-models.d.ts +0 -302
  82. package/dist/error-models.js +0 -203
  83. package/dist/error-models.js.map +0 -1
  84. package/dist/error-verdicts.d.ts +0 -46
  85. package/dist/error-verdicts.js +0 -120
  86. package/dist/error-verdicts.js.map +0 -1
  87. package/dist/run-may-have-started.d.ts +0 -31
  88. package/dist/run-may-have-started.js.map +0 -1
package/dist/errors.d.ts CHANGED
@@ -1,106 +1,67 @@
1
1
  /**
2
2
  * Pipelex SDK errors — the argument, transport, run-lifecycle, input-preparation and artifact
3
- * errors `PipelexApiClient` raises. Every one derives from `PipelexRequestError`, itself a
4
- * `PipelineRequestError` (the protocol base, re-exported from `mthds/protocol`), and so carries
5
- * a verdict: `retryable` and `errorDomain`, always decided, and `runMayHaveStarted`, which says
6
- * whether a failed start or execute may still have started a run. The one exported error outside
7
- * the family, `CodegenLockError`, declares the verdict's two members itself.
8
- */
9
- import { PipelineRequestError } from "mthds/protocol";
10
- import type { AnswerHeaders, Problem } from "mthds/protocol";
11
- import type { ValidationErrorItem } from "./models.js";
3
+ * errors `PipelexApiClient` raises. Every one derives from `PipelexRequestError`, itself the MTHDS
4
+ * standard's `ProblemError` (re-exported from `mthds/protocol`), and so carries its failure as a
5
+ * problem document: the runtime's own when it answered with one, and otherwise the problem the SDK
6
+ * builds for a failure it detects itself, under a registered code. A program branches on `code`,
7
+ * and on `domain`, `retry` and `nextStep` when it handles several codes alike; the rest of the
8
+ * problem (`params`, `location`, `errors`, `pipeline_run_id`, `request_id` and any member the
9
+ * runtime added) is read off `problem`. The Python twin, `pipelex-sdk`, builds the same code for
10
+ * every failure, which the shared case file `tests/fixtures/sdk-problems.json` pins in both suites.
11
+ *
12
+ * The exported errors outside the family, `CodegenLockError` and `ExactJsonUnsupportedError`, are
13
+ * `ProblemError`s too.
14
+ */
15
+ import { ProblemError } from "mthds/protocol";
16
+ import type { AnswerHeaders, Problem, ProblemItem } from "mthds/protocol";
12
17
  import type { ArtifactScope, DownloadArtifactsResult } from "./artifacts.js";
13
- import type { FieldError, MigrationErrorBlock, ProblemDetails, ProviderErrorMetadata, RunErrorReport, UserAction } from "./error-models.js";
14
18
  import type { RunStatus } from "./runs.js";
15
- export { PipelineRequestError };
19
+ export { ProblemError };
16
20
  /**
17
- * Who can fix a failure:
18
- *
19
- * - `input` — the caller, by changing the request: the inputs, the method, a reference, an
20
- * argument.
21
- * - `config` — someone changing the environment: the base URL, the credential, the plan, the
22
- * deployment.
23
- * - `runtime` — nobody beforehand: a fault during execution or in the service.
24
- *
25
- * The set is closed: the hosted envelope spec names these three, so a fourth would be a contract
26
- * change and would reach the SDK as one.
21
+ * The problem of an argument refused before any request left: `client.argument_invalid`, naming
22
+ * the argument and why it was refused, as an identifier (`not_a_string`, `mutually_exclusive`, …).
27
23
  */
28
- export type ErrorDomain = "input" | "config" | "runtime";
29
- /** Whether a value is one of the three error domains. */
30
- export declare function isErrorDomain(value: unknown): value is ErrorDomain;
24
+ export declare function argumentInvalidProblem(argument: string, reason: string): Problem;
31
25
  /**
32
- * The verdict an error carries: whether asking again can plausibly succeed (`retryable`), and who
33
- * can fix the failure (`errorDomain`). Both are always decided.
34
- *
35
- * "Retryable" says a retry can succeed, and on a request that may create a run, that it cannot
36
- * start a second one: a failed `start` or `execute` that may still have started a run (an error
37
- * whose `runMayHaveStarted` is true) is never retryable, whatever the server or the fallback table
38
- * says, since asking again could pay for the run twice. Everywhere else it says nothing about
39
- * whether the first attempt had an effect.
26
+ * The problem of an answer the SDK cannot use as the route's answer: `client.response_unreadable`,
27
+ * naming its status, and the run it is about as its member when there is one.
40
28
  */
41
- export interface ErrorVerdict {
42
- readonly retryable: boolean;
43
- readonly errorDomain: ErrorDomain;
44
- }
29
+ export declare function responseUnreadableProblem(status: number, runId?: string): Problem;
30
+ /** The problem the standard reads from an answer's status alone, as for a body that is no problem document. */
31
+ export declare function statusProblem(status: number): Problem;
45
32
  /**
46
- * The base of every error this SDK raises over a request, carrying the verdict as two readonly
47
- * own properties, `retryable` and `errorDomain`, and a third, `runMayHaveStarted`. Each subclass
48
- * passes its verdict to this constructor, so a class that forgets one does not compile, and every
49
- * class says its verdict where it is defined.
50
- *
51
- * `runMayHaveStarted` is false unless the subclass passes it: only `ApiUnreachableError` and
52
- * `ApiResponseError` built for a request that may create a run, and `PipelineExecuteTimeoutError`,
53
- * ever carry it as true, and when they do, `retryable` is false whatever the verdict passed.
54
- *
55
- * It refines the standard's `PipelineRequestError`, so `instanceof PipelineRequestError` still
56
- * matches every SDK error. To read a verdict from anything a `catch` holds, use
57
- * `errorVerdictOf`, which also reads it off an error raised by another copy of this SDK, and
58
- * `runMayHaveStartedOf` for the third member.
59
- */
60
- export declare abstract class PipelexRequestError extends PipelineRequestError implements ErrorVerdict {
61
- /** Whether asking again can plausibly succeed. Always decided. */
62
- readonly retryable: boolean;
63
- /** Who can fix the failure: `input`, `config` or `runtime`. Always decided. */
64
- readonly errorDomain: ErrorDomain;
65
- /**
66
- * Whether the failed request may still have started a run whose id never reached the caller:
67
- * a `start` or an `execute` (and so `startAndWaitForResult`'s start, or the blocking execute it
68
- * falls back to) that failed in a way that does not prove the server started nothing. When it
69
- * is true, `retryable` is false: look the run up in the run history before starting it again.
70
- * False for every other request, a wait on a run already named included. Always decided.
71
- */
72
- readonly runMayHaveStarted: boolean;
73
- constructor(message: string, verdict: ErrorVerdict, options?: {
74
- cause?: unknown;
75
- runMayHaveStarted?: boolean;
76
- });
77
- }
33
+ * Whether a storage answer's `status` refuses the request for its timing or fails in a way a later
34
+ * attempt can pass: a `408`, a `429`, or a `5xx` other than `501`.
35
+ */
36
+ export declare function isTransientStorageStatus(status: number): boolean;
78
37
  /**
79
- * The verdict of anything a `catch` holds: the pair from an `Error` carrying a boolean
80
- * `retryable` and a known `errorDomain`, else the verdict of the MTHDS standard's problem an
81
- * `Error` carries as `problem`, and `undefined` otherwise.
82
- *
83
- * The check is structural rather than `instanceof`, so it reads every error of this SDK, of
84
- * another copy of it installed beside this one, and of a consumer's own subclass. An error of the
85
- * standard's own client (`mthds`) carries its verdict on its problem, as `domain` and `retry` in
86
- * the standard's vocabulary, and reads as that problem's verdict in this SDK's
87
- * (`problemVerdict`), whatever the runner's body held beside it. `undefined` means the error
88
- * carries no verdict: the `RangeError` or `TypeError` the SDK raises for an argument of the
89
- * wrong type or range before any request is sent (a bug in the calling code), the caller's own
90
- * abort, which the client rethrows untouched, or anything else a `try` block threw. An argument
91
- * the client refuses for what it asks is a `RequestArgumentError`, which carries one.
38
+ * The problem of a storage answer the SDK reads by its status, storage answering no problem
39
+ * document: `runtime.unavailable` for a transient status ({@link isTransientStorageStatus}), so
40
+ * that asking again can succeed; `runtime.unsupported` for a `501`, storage not implementing the
41
+ * request it was sent; and `client.response_unreadable` naming the status otherwise, an answer the
42
+ * SDK has no reading for.
92
43
  */
93
- export declare function errorVerdictOf(err: unknown): ErrorVerdict | undefined;
44
+ export declare function storageStatusProblem(status: number): Problem;
94
45
  /**
95
- * Whether anything a `catch` holds is a failed run start that may still have started a run: true
96
- * only for an `Error` carrying `runMayHaveStarted` as `true`.
46
+ * The base of every error this SDK raises over a request, carrying the failure as `problem`.
47
+ *
48
+ * It refines the standard's `ProblemError`, so every getter that reads the problem is there:
49
+ * `code`, the member a program branches on; `domain`, who must act (`input`, `method`,
50
+ * `account`, `operator` or `runtime`); `retry`, whether sending the same request again can succeed
51
+ * (`yes`, `no`, or `outcome_unknown` where a run may already exist and must be read, never started
52
+ * again); `nextStep`, what to do; `retryAfter`, the seconds to wait before a repeat when the
53
+ * problem gives them; and `requestId`, the id to hand to support. `instanceof ProblemError` and
54
+ * `instanceof PipelineRequestError` match every SDK error, as does `mthds`'s `isProblemError`.
97
55
  *
98
- * The check is structural, as `errorVerdictOf`'s is, so it reads an error raised by another copy
99
- * of this SDK installed beside this one. Anything else is false: an error of a request that
100
- * cannot start a run, an `mthds` error, which the standard's client never raises over a start of
101
- * this SDK, and a value that is not an `Error`.
56
+ * The message is the SDK's own sentence, as it always was, rather than the problem's: the problem's
57
+ * `detail` and `next_step.detail` are on `problem` for whoever renders them. Its subclasses are
58
+ * meant to be raised, never this class itself.
102
59
  */
103
- export declare function runMayHaveStartedOf(err: unknown): boolean;
60
+ export declare abstract class PipelexRequestError extends ProblemError {
61
+ constructor(message: string, problem: Problem, options?: {
62
+ cause?: unknown;
63
+ });
64
+ }
104
65
  /**
105
66
  * The SDK refused a call's arguments before sending any request: no run source given to
106
67
  * `execute()` or `start()`, run sources or method selectors that exclude each other, a selector
@@ -112,16 +73,17 @@ export declare function runMayHaveStartedOf(err: unknown): boolean;
112
73
  * to 255 visible ASCII characters, or a base URL that is not host-only. Nothing reached the API,
113
74
  * so the message says what to change.
114
75
  *
115
- * Its verdict is `input`, not retryable — the caller must change the arguments — unless
116
- * `options.verdict` declares another: the client declares `config` for a base URL that is not
117
- * host-only, since it typically comes from `PIPELEX_BASE_URL`. A refusal the standard's own
118
- * check raises (`assertExclusiveRunSources`) is rethrown as this class with the same message, the
119
- * standard's error as `cause`.
76
+ * Its problem is `client.argument_invalid`, unless `options.problem` gives another: the client
77
+ * gives `client.not_configured` naming `base_url` for a base URL that is not host-only, since it
78
+ * typically comes from `PIPELEX_BASE_URL`. One built from a message alone names the argument
79
+ * `arguments`, for the reason `unspecified`. A refusal the standard's own check raises
80
+ * (`assertExclusiveRunSources`) is rethrown as this class with the same message, the standard's
81
+ * error as `cause`.
120
82
  */
121
83
  export declare class RequestArgumentError extends PipelexRequestError {
122
84
  constructor(message: string, options?: {
123
85
  cause?: unknown;
124
- verdict?: ErrorVerdict;
86
+ problem?: Problem;
125
87
  });
126
88
  }
127
89
  /**
@@ -130,20 +92,22 @@ export declare class RequestArgumentError extends PipelexRequestError {
130
92
  * subclass to branch on the semantic category. All preparation failures are
131
93
  * raised BEFORE any run is created — a run never triggers a hidden upload.
132
94
  *
133
- * Its verdict is `input`, not retryable — the asset, the inputs or the method selector must
134
- * change — unless `options.verdict` declares another: the SDK's own subclasses do, and so can a
135
- * consumer's, such as a form reporting a missing input in its own words.
95
+ * Its problem is the one `options.problem` gives: the SDK's own subclasses state theirs, a direct
96
+ * raise gives `client.argument_invalid` for an argument refused or the wrapped error's for a
97
+ * refusal the API answered, and a consumer's subclass, such as a form reporting a missing input in
98
+ * its own words, may give any. One built with none, from a message alone, carries
99
+ * `client.argument_invalid` naming `inputs`, for the reason `unspecified`.
136
100
  */
137
101
  export declare class InputPreparationError extends PipelexRequestError {
138
102
  constructor(message: string, options?: {
139
103
  cause?: unknown;
140
- verdict?: ErrorVerdict;
104
+ problem?: Problem;
141
105
  });
142
106
  }
143
107
  /**
144
108
  * A local asset could not be turned into bytes: a missing or unreadable path, or
145
109
  * a path string in a non-Node runtime (path strings are Node-only). `source` is
146
- * the offending path.
110
+ * the offending path. Its problem is `input.file_unreadable`, naming the path.
147
111
  */
148
112
  export declare class InvalidLocalSourceError extends InputPreparationError {
149
113
  readonly source: string;
@@ -162,7 +126,8 @@ export declare class InvalidLocalSourceError extends InputPreparationError {
162
126
  * As on `UploadNotAllowedError`, `inputName` is the input the value belongs to and `inputPath`
163
127
  * where it sits inside that input (`report.attachments[1]`, or the name alone for a top-level
164
128
  * file). The message names that path and describes the value by its kind, never by its content,
165
- * since the value is the caller's data.
129
+ * since the value is the caller's data. Its problem is `input.invalid`, naming the input and the
130
+ * path inside it.
166
131
  */
167
132
  export declare class InvalidInputValueError extends InputPreparationError {
168
133
  readonly inputName: string;
@@ -188,8 +153,9 @@ export type UploadNotAllowedKind = "local_path" | "data_url" | "bytes";
188
153
  * reads a file of its own because the caller named it. `inputName` is the input the value belongs
189
154
  * to, `inputPath` where it sits inside that input (`report.attachments[1]`, or the name alone for a
190
155
  * top-level file), and `valueKind` what it is. The value itself is neither in the message nor on
191
- * the error, since it is the caller's data. Its verdict is `input`, not retryable: the caller must
192
- * pass an `http(s)` URL or a `pipelex-storage://` reference instead.
156
+ * the error, since it is the caller's data. Its problem is `client.argument_invalid`, naming the
157
+ * input's path and the value's kind as the reason: the caller must pass an `http(s)` URL or a
158
+ * `pipelex-storage://` reference instead.
193
159
  */
194
160
  export declare class UploadNotAllowedError extends InputPreparationError {
195
161
  readonly inputName: string;
@@ -205,16 +171,15 @@ export declare class UploadNotAllowedError extends InputPreparationError {
205
171
  }
206
172
  /**
207
173
  * The pipe I/O answer said the method does not load (`is_valid: false`), so its signature cannot
208
- * be read and no input can be prepared: the method, not the inputs, must change.
209
- * `validationErrors` holds the answer's items, each kept when it carries a string `category` and
210
- * `message`, possibly none; `serverMessage` is the answer's own `message` when it is a string. The
211
- * error's message names the first item's message, else the answer's own.
174
+ * be read and no input can be prepared: the method, not the inputs, must change. Its problem is
175
+ * `method.invalid`, whose `errors` are the answer's problem items, each read member by member
176
+ * (see `readProblemItems`), possibly none; `serverMessage` is the answer's own `message` when it is
177
+ * a string. The error's message names the first item's `detail`, else the answer's own message.
212
178
  */
213
179
  export declare class MethodLoadError extends InputPreparationError {
214
- readonly validationErrors: ValidationErrorItem[];
215
180
  readonly serverMessage: string | undefined;
216
181
  constructor(message: string, details: {
217
- validationErrors: ValidationErrorItem[];
182
+ errors: ProblemItem[];
218
183
  serverMessage?: string | undefined;
219
184
  }, options?: {
220
185
  cause?: unknown;
@@ -234,7 +199,7 @@ export declare class MethodLoadError extends InputPreparationError {
234
199
  * refusal of the asset: they refuse the request for its timing, and are an
235
200
  * `UploadTransportError`.
236
201
  */
237
- export type RejectedAssetCode = "too_large" | "grant_used" | "grant_expired" | "signature_mismatch" | "unsigned_header" | "store_refused";
202
+ export type RejectedAssetReason = "too_large" | "grant_used" | "grant_expired" | "signature_mismatch" | "unsigned_header" | "store_refused";
238
203
  /**
239
204
  * The server or storage refused the asset — most commonly a `413` past the
240
205
  * service-defined size cap, or storage refusing an upload with a grant. A storage
@@ -242,25 +207,29 @@ export type RejectedAssetCode = "too_large" | "grant_used" | "grant_expired" | "
242
207
  * time out or throttle the request, a `400 RequestTimeout` and a `409
243
208
  * ConditionalRequestConflict` are an `UploadTransportError`. The SDK
244
209
  * does not impose a client-side cap; it surfaces the refusal. `filename` and
245
- * `status` locate it, and `code` says why: the SDK sets it on every one it raises,
210
+ * `status` locate it, and `reason` says why: the SDK sets it on every one it raises,
246
211
  * so it is undefined only on one a caller constructs without it.
212
+ *
213
+ * Its problem is the refusal's as the API answered it, which `uploadFile` passes, and otherwise
214
+ * the one the standard reads from `status` alone, storage answering no problem document.
247
215
  */
248
216
  export declare class RejectedAssetError extends InputPreparationError {
249
217
  readonly filename: string;
250
218
  readonly status: number;
251
- readonly code: RejectedAssetCode | undefined;
219
+ readonly reason: RejectedAssetReason | undefined;
252
220
  constructor(message: string, filename: string, status: number, options?: {
253
221
  cause?: unknown;
254
- code?: RejectedAssetCode;
222
+ reason?: RejectedAssetReason;
223
+ problem?: Problem;
255
224
  });
256
225
  }
257
226
  /**
258
227
  * The configured deployment does not support upload (no `/v1/upload` route, seen
259
228
  * as a `404` other than a test file's unknown method, which is a {@link TestFileRefusedError}).
260
229
  * Upload is a hosted Pipelex-product capability even though the SDK
261
- * can be pointed at other base URLs. Its verdict is `config`, not retryable: the base URL
262
- * must point at a deployment that serves upload. `filename` is the file whose upload met it, as
263
- * `uploadFile` sent it.
230
+ * can be pointed at other base URLs. Its problem is `runtime.unsupported`, naming file upload as
231
+ * the capability the deployment lacks: the base URL must point at a deployment that serves
232
+ * upload. `filename` is the file whose upload met it, as `uploadFile` sent it.
264
233
  */
265
234
  export declare class UnsupportedUploadCapabilityError extends InputPreparationError {
266
235
  readonly filename: string | undefined;
@@ -271,8 +240,11 @@ export declare class UnsupportedUploadCapabilityError extends InputPreparationEr
271
240
  }
272
241
  /**
273
242
  * Upload was not authorized — a `401`, or a `403` from the upload route other than a test file's
274
- * `role_not_permitted`, which is a {@link TestFileRefusedError}. Its verdict is `config`, not
275
- * retryable: the credential must change. `filename` is the file whose upload was refused, as
243
+ * refused role, which is a {@link TestFileRefusedError}. Its problem is the server's own when the
244
+ * wrapped error, which `uploadFile` passes as `cause`, answered a problem document. Otherwise it is
245
+ * `auth.invalid_credential` when the request carried a credential and `auth.missing_credential`
246
+ * when it carried none, as `options.credentialSent` says, and the wrapped error's reading of the
247
+ * status when the caller does not say. `filename` is the file whose upload was refused, as
276
248
  * `uploadFile` sent it.
277
249
  */
278
250
  export declare class UploadAuthenticationError extends InputPreparationError {
@@ -281,6 +253,7 @@ export declare class UploadAuthenticationError extends InputPreparationError {
281
253
  constructor(message: string, status: number, options?: {
282
254
  cause?: unknown;
283
255
  filename?: string;
256
+ credentialSent?: boolean;
284
257
  });
285
258
  }
286
259
  /**
@@ -288,36 +261,37 @@ export declare class UploadAuthenticationError extends InputPreparationError {
288
261
  * than on the message. A test file is a statement about a method, so the route holds it to what
289
262
  * changing that method takes:
290
263
  *
291
- * - `role_not_permitted` — a `403` coded `role_not_permitted`: the caller's role in the
292
- * organization may not change methods, as a runner's may not. Upload the file as `uploaded`,
293
- * or with the credential of a member who may change methods.
294
- * - `method_not_found` — a `404` coded `not_found`: the method the test file names is not one of
295
- * the organization's.
296
- * - `method_being_deleted` — a `409` coded `method_being_deleted`: the method the test file names
297
- * is being erased.
264
+ * - `role_not_permitted` — the caller's role in the organization may not change methods, as a
265
+ * runner's may not (the route's `auth.forbidden`). Upload the file as `uploaded`, or with the
266
+ * credential of a member who may change methods.
267
+ * - `method_not_found` — the method the test file names is not one of the organization's (the
268
+ * route's `pipelex.catalog.not_found`).
269
+ * - `method_being_deleted` — the method the test file names is being erased (the route's
270
+ * `pipelex.catalog.being_deleted`).
298
271
  */
299
- export type TestFileRefusalCode = "role_not_permitted" | "method_not_found" | "method_being_deleted";
272
+ export type TestFileRefusalReason = "role_not_permitted" | "method_not_found" | "method_being_deleted";
300
273
  /**
301
274
  * The upload route refused a test file (`kind: "test"`) for what it claims, never for its bytes:
302
275
  * the caller's role may not change methods, or the method it names is unknown or being erased.
303
- * `code` says which; the SDK sets it on every one it raises, so it is undefined only on one a
276
+ * `reason` says which; the SDK sets it on every one it raises, so it is undefined only on one a
304
277
  * caller constructs without it. `status` is the HTTP status, `filename` the file `uploadFile` was
305
278
  * sending and `methodId` the method it named, and the wrapped `ApiResponseError` is reachable via
306
279
  * `cause`.
307
280
  *
308
- * Its verdict is the wrapped error's when `cause` carries one, the server's own; otherwise `code`
309
- * decides: `role_not_permitted` is `config`, since the caller's role must change, and the other
310
- * two are `input`, since the request must name another method; none is retryable.
281
+ * Its problem is the wrapped error's when `cause` carries one, the server's own. Otherwise it is
282
+ * `auth.forbidden` for `role_not_permitted`, naming a role that may change methods as the
283
+ * requirement, and `client.argument_invalid` naming `method_id` for the other two, the reason as
284
+ * the reason.
311
285
  */
312
286
  export declare class TestFileRefusedError extends InputPreparationError {
313
287
  readonly status: number | undefined;
314
- readonly code: TestFileRefusalCode | undefined;
288
+ readonly reason: TestFileRefusalReason | undefined;
315
289
  readonly filename: string | undefined;
316
290
  readonly methodId: string | undefined;
317
291
  constructor(message: string, options?: {
318
292
  cause?: unknown;
319
293
  status?: number;
320
- code?: TestFileRefusalCode;
294
+ reason?: TestFileRefusalReason;
321
295
  filename?: string;
322
296
  methodId?: string;
323
297
  });
@@ -345,44 +319,52 @@ export declare class TestFileRefusedError extends InputPreparationError {
345
319
  * `uploadWithGrant`, storage's `408` or `429`: it timed out or throttled the request,
346
320
  * which a later attempt can pass.
347
321
  */
348
- export type UploadTransportCode = "timeout" | "unreachable" | "server_error" | "storage_timeout" | "conflict" | "redirected" | "invalid_grant_url" | "unexpected";
322
+ export type UploadTransportReason = "timeout" | "unreachable" | "server_error" | "storage_timeout" | "conflict" | "redirected" | "invalid_grant_url" | "unexpected";
349
323
  /**
350
324
  * A network or server fault reaching the upload route or storage — an unreachable
351
325
  * host, a timeout, a `5xx`, a refused redirect, storage timing out on the body,
352
326
  * storage timing out or throttling the request (a `408` or a `429`), or any other
353
- * unexpected `upload()` failure. `code` says which: the SDK sets it on
327
+ * unexpected `upload()` failure. `reason` says which: the SDK sets it on
354
328
  * every one it raises, so it is undefined only on one a caller constructs without
355
329
  * it. `status` is the HTTP status when a response produced it, and undefined when
356
330
  * none did. From `uploadFile` the wrapped `ApiResponseError` is also reachable via
357
331
  * `cause`, and `filename` is the file it was sending; `uploadWithGrant` wraps no response,
358
332
  * because storage's error body can echo the grant's credential, and leaves `filename` undefined.
359
333
  *
360
- * Its verdict is the wrapped error's when `cause` carries one: `uploadFile` wraps the
361
- * `ApiResponseError` or `ApiUnreachableError` the client's `upload()` threw, and `code` is too
362
- * coarse to judge it by (a `402` plan limit is `unexpected`, like a malformed answer). Otherwise
363
- * — always the case from `uploadWithGrant`, which wraps no response — `code` decides: `timeout`,
364
- * `storage_timeout` and `conflict` are `runtime` and retryable, `conflict` because storage
365
- * documents its `409 ConditionalRequestConflict` as retryable and the grant is not spent by it (a
366
- * spent hashless grant is the `412` of a `RejectedAssetError` with code `grant_used`); `server_error` is
367
- * `runtime`, and retryable when the fallback table a refused API request reads would call its
368
- * `status` retryable — any `5xx` but a `501`, which storage answers for a request it does not
369
- * implement — or when it carries no status; `unexpected` is `runtime`, and retryable when that
370
- * table would call its `status` retryable — storage's `408` or `429`, refused for its timing —
371
- * and not retryable for any other status or none; `unreachable` is `config` and retryable, like
372
- * `ApiUnreachableError`; `redirected` is `config` and not retryable; `invalid_grant_url` and no
373
- * code at all are `runtime` and not retryable.
334
+ * Its problem is `options.problem` when given, else the wrapped error's when `cause` carries one:
335
+ * `uploadFile` wraps the `ApiResponseError` or `ApiUnreachableError` the client's `upload()`
336
+ * threw. Otherwise — always the case from `uploadWithGrant`, which wraps no response — `reason`
337
+ * decides (`uploadTransportProblem`).
374
338
  */
375
339
  export declare class UploadTransportError extends InputPreparationError {
376
340
  readonly status: number | undefined;
377
- readonly code: UploadTransportCode | undefined;
341
+ readonly reason: UploadTransportReason | undefined;
378
342
  readonly filename: string | undefined;
379
343
  constructor(message: string, options?: {
380
344
  cause?: unknown;
381
345
  status?: number;
382
- code?: UploadTransportCode;
346
+ reason?: UploadTransportReason;
383
347
  filename?: string;
348
+ problem?: Problem;
384
349
  });
385
350
  }
351
+ /**
352
+ * The problem of an upload transport failure that wraps no error carrying one, by its reason and
353
+ * the status storage answered:
354
+ *
355
+ * - `timeout`, `unreachable`, `storage_timeout` and `conflict` are `runtime.unavailable`: storage,
356
+ * a service the upload depends on, did not take the file, and a later attempt can (the SDK's
357
+ * own raise sites give `client.timeout` and `client.unreachable` instead, naming the limit and
358
+ * the host);
359
+ * - `server_error`, `unexpected` and no reason at all are `storageStatusProblem`'s reading of the
360
+ * status: `runtime.unavailable` for a `408`, a `429` or a `5xx` other than `501`,
361
+ * `runtime.unsupported` for a `501`, `client.response_unreadable` for any other status; a
362
+ * `server_error` with no status is `runtime.unavailable`, and the others `runtime.unexpected`;
363
+ * - `redirected` is `runtime.misconfigured`: storage redirecting a signed upload is a fault of the
364
+ * deployment;
365
+ * - `invalid_grant_url` is `client.response_unreadable`: the grant the API answered is unusable.
366
+ */
367
+ export declare function uploadTransportProblem(reason: UploadTransportReason | undefined, status: number | undefined): Problem;
386
368
  /**
387
369
  * Base class for the failures the artifact operations raise on their own
388
370
  * (`fetchArtifact` / `downloadArtifacts`) — the download twin of
@@ -393,15 +375,16 @@ export declare class UploadTransportError extends InputPreparationError {
393
375
  * failures on the resolve route (`ApiResponseError`, `ApiUnreachableError`)
394
376
  * and the run-lifecycle errors propagate unchanged, so they are not subclasses.
395
377
  *
396
- * Its verdict is `runtime`, not retryable, unless `options.verdict` declares another: the SDK
397
- * declares `input` where it refuses an argument (a `scope`, a bound, a location) and `config`
398
- * where the environment refuses the download (a runtime with no filesystem, a directory that
399
- * cannot be created).
378
+ * Its problem is `options.problem`, else `runtime.unexpected`: the SDK gives
379
+ * `client.argument_invalid` where it refuses an argument (a `scope`, a bound, a location),
380
+ * `runtime.unsupported` for a runtime with no filesystem, `client.write_failed` for a directory
381
+ * that cannot be created, and `client.response_unreadable` for a resolution that answered the
382
+ * wrong count of items.
400
383
  */
401
384
  export declare class ArtifactOperationError extends PipelexRequestError {
402
385
  constructor(message: string, options?: {
403
386
  cause?: unknown;
404
- verdict?: ErrorVerdict;
387
+ problem?: Problem;
405
388
  });
406
389
  }
407
390
  /**
@@ -409,7 +392,7 @@ export declare class ArtifactOperationError extends PipelexRequestError {
409
392
  * results: `main_stuff` or `working_memory` is `null`, or the key is missing
410
393
  * from the body altogether. Distinct from an empty walk over a present scope,
411
394
  * which is a produced verdict with no artifacts. `scope` names the scope,
412
- * `runId` the run.
395
+ * `runId` the run. Its problem is `client.response_unreadable`, naming the run.
413
396
  */
414
397
  export declare class ScopeUnavailableError extends ArtifactOperationError {
415
398
  readonly scope: ArtifactScope;
@@ -420,31 +403,43 @@ export declare class ScopeUnavailableError extends ArtifactOperationError {
420
403
  }
421
404
  /**
422
405
  * One reference could not be turned into a bounded response by `fetchArtifact`.
423
- * `code` says why, in a closed vocabulary the download verdict shares for its
424
- * per-item errors: the resolve route's own per-reference codes
406
+ * `reason` says why, in a closed vocabulary the download verdict shares for its
407
+ * per-item errors: the resolve route's own per-reference reasons
425
408
  * (`invalid_storage_uri`, `forbidden`), then the fetch boundary's —
426
409
  * `unsupported_url`, `plain_http_refused`, `redirect_refused`, `store_refused`
427
410
  * (a 401/403 from the object store), `not_found` (404/410), `store_error`
428
- * (any other non-2xx), `too_large`, `timeout`, `network`. `status` is the
429
- * store's HTTP status when one was received. `downloadArtifacts` never lets
430
- * this escape: it becomes the item's `error`.
431
- *
432
- * Its verdict follows `code`: `invalid_storage_uri`, `forbidden`, `unsupported_url`, `not_found`
433
- * and `too_large` are `input` and not retryable, since the reference or the bound must change;
434
- * `plain_http_refused` is `config` and not retryable; `redirect_refused` and `store_refused` are
435
- * `runtime` and not retryable; `timeout` and `network` are `runtime` and retryable; `store_error`
436
- * is `runtime`, and retryable when the fallback table a refused API request reads would call its
437
- * `status` retryable — a `408`, a `429` or a `5xx` other than `501` — and not retryable for any
438
- * other status or none. A code this version does not know is `runtime` and not retryable.
411
+ * (any other non-2xx), `too_large`, `timeout`, `network`, and `unknown` for a failure the SDK
412
+ * cannot place. `status` is the store's HTTP status when one was received. `downloadArtifacts`
413
+ * never lets this escape: it becomes the item's `error`.
414
+ *
415
+ * Its problem is `options.problem` when given, else follows `reason` and `status`
416
+ * (`artifactFetchProblem`). The SDK gives `client.download_limit_exceeded` naming the cap for
417
+ * `too_large`, `client.timeout` naming the budget for `timeout`, and `client.unreachable` naming
418
+ * the store's origin for `network`.
439
419
  */
440
420
  export declare class ArtifactFetchError extends ArtifactOperationError {
441
421
  readonly uri: string;
442
- readonly code: string;
422
+ readonly reason: string;
443
423
  readonly status: number | undefined;
444
- constructor(message: string, uri: string, code: string, status?: number, options?: {
424
+ constructor(message: string, uri: string, reason: string, status?: number, options?: {
445
425
  cause?: unknown;
426
+ problem?: Problem;
446
427
  });
447
428
  }
429
+ /**
430
+ * The problem of one reference's fetch failure that its raise site states none for, by its reason
431
+ * and the store's status: `input.reference_not_found` naming the reference for
432
+ * `invalid_storage_uri`, `forbidden` and `not_found`; `client.link_refused` for
433
+ * `unsupported_url`, `plain_http_refused` and `redirect_refused`; for `store_error` and
434
+ * `store_refused`, the object store failing or refusing a link the platform has just signed,
435
+ * `storageStatusProblem`'s reading of the store's status (`runtime.unavailable` for a `408`, a
436
+ * `429` or a `5xx` other than `501`, `runtime.unsupported` for a `501`, and
437
+ * `client.response_unreadable` naming any other status, a `401` or a `403` included), and
438
+ * `runtime.unavailable` when no status is known; `runtime.unavailable` for `timeout` and
439
+ * `network`; and `runtime.unexpected` otherwise, `unknown` and a reason this version does not know
440
+ * included.
441
+ */
442
+ export declare function artifactFetchProblem(reason: string, uri: string, status?: number): Problem;
448
443
  /**
449
444
  * The resolve route refused the caller's credential (`401` / `403`) during a
450
445
  * `downloadArtifacts` call. No further reference can be resolved with it, so
@@ -452,14 +447,17 @@ export declare class ArtifactFetchError extends ArtifactOperationError {
452
447
  * carries the result as it stood: every item saved before the refusal, and
453
448
  * the rest marked `aborted`. `status` is the route's status; the wrapped
454
449
  * `ApiResponseError` is reachable via `cause`. (`verdict` is the download's result, not the
455
- * error's own: that is `retryable` and `errorDomain`, `config` and not retryable, since the
456
- * credential must change.)
450
+ * error's own problem.) Its problem is the server's own when the wrapped error answered a problem
451
+ * document; otherwise `auth.invalid_credential`, or `auth.missing_credential` when
452
+ * `options.credentialSent` says the request carried no credential, and the wrapped error's reading
453
+ * of the status when the caller does not say.
457
454
  */
458
455
  export declare class ArtifactAuthenticationError extends ArtifactOperationError {
459
456
  readonly status: number;
460
457
  readonly verdict: DownloadArtifactsResult;
461
458
  constructor(message: string, status: number, verdict: DownloadArtifactsResult, options?: {
462
459
  cause?: unknown;
460
+ credentialSent?: boolean;
463
461
  });
464
462
  }
465
463
  /** Which way a file of a method's tree was moving when its transfer failed. */
@@ -474,7 +472,7 @@ export type MethodFileTransferOperation = "upload" | "download";
474
472
  * - `mismatch`: a download's bytes are not the file the listing names, another size or another
475
473
  * SHA-256.
476
474
  */
477
- export type MethodFileTransferCode = "unreachable" | "storage_error" | "refused" | "mismatch";
475
+ export type MethodFileTransferReason = "unreachable" | "storage_error" | "refused" | "mismatch";
478
476
  /**
479
477
  * A file of a method's tree that could not be moved between this machine and the platform's
480
478
  * storage: thrown by `createMethod` and `writeDraft` when a file the organization lacks could not
@@ -484,68 +482,72 @@ export type MethodFileTransferCode = "unreachable" | "storage_error" | "refused"
484
482
  * `writeMethodTree` when a saved file could not be downloaded through its link, or its bytes are
485
483
  * not the file the listing names.
486
484
  *
487
- * `operation` says which way the file was moving, `code` why it failed, `sha256` which bytes,
485
+ * `operation` says which way the file was moving, `reason` why it failed, `sha256` which bytes,
488
486
  * `path` the tree path when one is known, and `status` storage's HTTP status when it answered.
489
487
  * Neither the message nor any member carries the link, whose query is a bearer credential, nor
490
488
  * storage's error body, which can echo the signed request, and it keeps no `cause`, since the
491
489
  * failure fetch throws can quote the URL.
492
490
  *
493
- * Its domain is always `runtime`, since neither the call nor the environment is at fault:
494
- * `unreachable`, `storage_error` and `mismatch` are retryable, since the same transfer can succeed
495
- * later, and `refused` is not. A download refused for an expired link succeeds once the method is
496
- * read again, which serves fresh links. A code this version does not know is not retryable.
491
+ * Its problem follows `reason` (`methodFileTransferProblem`): `unreachable` and `storage_error`
492
+ * are `runtime.unavailable`, since the same transfer can succeed later; `refused` is
493
+ * `storageStatusProblem`'s reading of storage's status (`client.response_unreadable` naming it, or
494
+ * `runtime.unsupported` for a `501`), a download refused for an expired link succeeding once the
495
+ * method is read again, which serves fresh links; and `mismatch` is `client.response_unreadable`.
497
496
  */
498
497
  export declare class MethodFileTransferError extends PipelexRequestError {
499
498
  readonly operation: MethodFileTransferOperation;
500
- readonly code: MethodFileTransferCode;
499
+ readonly reason: MethodFileTransferReason;
501
500
  readonly sha256: string | undefined;
502
501
  readonly path: string | undefined;
503
502
  readonly status: number | undefined;
504
503
  constructor(message: string, details: {
505
504
  operation: MethodFileTransferOperation;
506
- code: MethodFileTransferCode;
505
+ reason: MethodFileTransferReason;
507
506
  sha256?: string;
508
507
  path?: string;
509
508
  status?: number;
510
509
  });
511
510
  }
511
+ /** The problem of a failed transfer of a method's file, by its reason and storage's status. */
512
+ export declare function methodFileTransferProblem(reason: MethodFileTransferReason, status: number | undefined): Problem;
512
513
  /**
513
514
  * Thrown when the Pipelex API host cannot be reached at all (DNS failure,
514
515
  * connection refused, TLS handshake failure, request timeout). The HTTP
515
516
  * exchange never produced a response — distinguish from `ApiResponseError`,
516
- * which represents a non-2xx response that did come back.
517
+ * which represents a response that did come back, a body that arrived and could not be decoded
518
+ * included.
517
519
  *
518
- * `code` is the underlying network error code when available
520
+ * `networkCode` is the underlying network error code when available
519
521
  * (`ECONNREFUSED`, `ENOTFOUND`, `ETIMEDOUT`, `EAI_AGAIN`, `ABORT_TIMEOUT`).
520
522
  *
521
- * Its verdict is `config` and retryable: the address or the network must be checked, and a later
522
- * attempt can get through. With the code `ABORT_TIMEOUT`, the SDK's own request timeout, it is
523
- * `runtime` and retryable instead: the API took the request and did not answer in time, which is
524
- * no fault of the base URL.
525
- *
526
- * On a request that may create a run (`options.mayStartRun`, which the client sets on `start` and
527
- * `execute`), `runMayHaveStarted` is true unless `cause`, the failure fetch threw, proves the
528
- * request never left: the name lookup, the connection or the TLS handshake failed. A reset, a time
529
- * limit or a body that could not be decoded proves nothing, so the run may have started and the
530
- * error is not retryable.
523
+ * Its problem is the transport's: `client.timeout`, naming the time limit, for the SDK's own time
524
+ * limit (`ABORT_TIMEOUT`) when the client gives it as `options.timeoutMs`, and
525
+ * `client.unreachable`, naming the base URL, otherwise. Both have `retry` `yes`. On a request that
526
+ * may create a run (`options.mayStartRun`, which the client sets on `start` and `execute`), it is
527
+ * `client.outcome_unknown` instead, whose `retry` is `outcome_unknown`, unless `cause`, the failure
528
+ * fetch threw, proves the request never left: the name lookup, the connection or the TLS handshake
529
+ * failed. A reset or a time limit proves nothing, so the run may have started.
531
530
  */
532
531
  export declare class ApiUnreachableError extends PipelexRequestError {
533
532
  readonly apiUrl: string;
534
- readonly code: string | undefined;
535
- constructor(message: string, apiUrl: string, code: string | undefined, options?: {
533
+ readonly networkCode: string | undefined;
534
+ constructor(message: string, apiUrl: string, networkCode: string | undefined, options?: {
536
535
  cause?: unknown;
537
536
  mayStartRun?: boolean;
537
+ timeoutMs?: number;
538
538
  });
539
539
  }
540
+ /** The SDK's own time limit ran out while the request was sent or answered. */
541
+ export declare const ABORT_TIMEOUT = "ABORT_TIMEOUT";
540
542
  /**
541
543
  * Thrown when the blocking `execute` (`POST /v1/execute`) is killed by the
542
544
  * hosted gateway's ~30s synchronous-request limit. The blocking path cannot
543
545
  * run methods longer than 30s behind the hosted gateway — use the durable run
544
546
  * lifecycle (start + poll) instead.
545
547
  *
546
- * Its verdict is `input`, not retryable: asking again meets the same limit, and the caller fixes
547
- * it by starting the run and polling. `runMayHaveStarted` is always true: the gateway gave up on
548
- * the request, and the run it carried goes on without its id reaching the caller.
548
+ * Its problem is `client.outcome_unknown`: the gateway gave up on the request, and the run it
549
+ * carried may go on without its id reaching the caller, so it is looked up in the run history
550
+ * rather than sent again, and the next one is started and polled.
549
551
  */
550
552
  export declare class PipelineExecuteTimeoutError extends PipelexRequestError {
551
553
  readonly elapsedMs: number;
@@ -553,49 +555,36 @@ export declare class PipelineExecuteTimeoutError extends PipelexRequestError {
553
555
  cause?: unknown;
554
556
  });
555
557
  }
558
+ /**
559
+ * The problem of a run that ended without success, `run.failed`, naming the run and its terminal
560
+ * status, with the run's own problem nested as `run_error` when there is one.
561
+ */
562
+ export declare function runFailedProblem(runId: string, status: RunStatus, runError?: Problem | null): Problem;
556
563
  /**
557
564
  * Thrown when a run reaches a terminal state that is not `COMPLETED` (`FAILED`, `CANCELLED`,
558
565
  * `TERMINATED`, `TIMED_OUT`) — by `waitForResult`, `startAndWaitForResult` and the artifact
559
566
  * download when the platform answers the results read with HTTP 409. (`getRunResult` returns
560
567
  * the same facts as its `failed` arm instead of throwing.)
561
568
  *
562
- * - `status` is the run's terminal status, read from the problem's `run_status` member, or from
563
- * its `detail` sentence on a platform that predates the member.
564
- * - `error` is the run's stored error report as the platform serves it, typed whole as
565
- * `RunErrorReport`: the runner's `error_type`, `message`, `title`, `type_uri`, `error_domain`,
566
- * `error_category`, `retryable`, `user_action`, `provider_metadata`, `caller_facing_message`,
567
- * `validation_errors` and anything newer through its index signature. Branch on
568
- * `error.error_domain`, `error.type_uri` and `error.retryable`; show `error.user_action` as the
569
- * next step. The platform serves the runner's STRICT projection, so `message` is the author's
570
- * copy only when `caller_facing_message` is `true` and the placeholder
571
- * `An internal error occurred.` otherwise, `user_action` comes only with caller-facing copy,
572
- * `provider_metadata` keeps only `status_code` and `retry_after_seconds`, and `model`,
573
- * `provider` and `migration` are absent; deciding what a person sees is still the consumer's.
574
- * A run the platform ended or settled itself carries the caller-facing report the platform
575
- * wrote, in the same shape. A cancelled, terminated or timed-out run carries a report when a
576
- * completion callback carried one, and a timed-out run otherwise the platform's timeout report.
577
- * `null` when the run ended with no stored report (one whose start failed, or one cancelled,
578
- * terminated or given its status by hand with no completion callback carrying a report).
579
- * - The error's own `message` is the problem's `detail`, which names the status and then the
580
- * report's message (`Run finished with status FAILED: <message>`), so printing the error
581
- * already tells the reason.
582
- * - `runId` locates the run, for a status read or a support request.
583
- *
584
- * Its verdict comes from the report. `errorDomain` is the report's `error_domain` when it is one
585
- * of the three domains, and `runtime` otherwise, including a run with no report. `retryable` is
586
- * true only when the report's `retryable` is `true`: a report that says nothing, and a run with
587
- * none, read as not retryable, since starting the run again spends credit and nothing says it
588
- * would succeed. The report keeps its own `retryable` as written, so a consumer that words the
589
- * unknown differently still can.
569
+ * - `problem` is `run.failed`, the results read's own problem document as the platform answered
570
+ * it, or the one the SDK builds for a failed run it learned of otherwise. Its `retry` is `no`:
571
+ * the run is over, and starting it again spends credit.
572
+ * - `runError` is the run's own problem, which `run.failed` nests as `run_error`: why the run did
573
+ * not succeed, under its own code (`run.cancelled`, `run.timed_out`, a model's or a method's
574
+ * code), with its own `domain`, `retry` and `next_step`. Branch on it to tell a run worth
575
+ * starting again from one whose method or inputs must change. `undefined` when the run ended
576
+ * with no problem stored.
577
+ * - `status` is the run's terminal status, `runId` the run.
590
578
  */
591
579
  export declare class RunFailedError extends PipelexRequestError {
592
580
  readonly runId: string;
593
581
  readonly status: RunStatus;
594
- readonly error: RunErrorReport | null;
595
582
  constructor(message: string, runId: string, status: RunStatus, options?: {
596
583
  cause?: unknown;
597
- error?: RunErrorReport | null;
584
+ problem?: Problem;
598
585
  });
586
+ /** The run's own problem, nested as `run_error`, when the run ended with one. */
587
+ get runError(): Problem | undefined;
599
588
  }
600
589
  /**
601
590
  * Thrown when a completed run cannot deliver its main stuff.
@@ -607,7 +596,8 @@ export declare class RunFailedError extends PipelexRequestError {
607
596
  * memory. `runId` locates the run. (An empty-but-present main stuff — `{ items: [] }`, `{ text:
608
597
  * "" }` — is a valid output and does NOT throw; only a genuinely absent one does.)
609
598
  *
610
- * Its verdict is `runtime`, not retryable: the API broke its own contract on a completed run.
599
+ * Its problem is `client.response_unreadable`, naming the run: the API broke its own contract on a
600
+ * completed run.
611
601
  */
612
602
  export declare class MissingMainStuffError extends PipelexRequestError {
613
603
  readonly runId: string;
@@ -618,7 +608,8 @@ export declare class MissingMainStuffError extends PipelexRequestError {
618
608
  * terminal state. The run is NOT cancelled — it keeps executing server-side and
619
609
  * can be resumed later by `runId` (the poll loop just stopped waiting).
620
610
  *
621
- * Its verdict is `runtime` and retryable: the run is still going, and waiting again can succeed.
611
+ * Its problem is `client.follow_failed`, naming the run: its `retry` is `outcome_unknown` and its
612
+ * step `read_run`, since the run goes on and is read by its id, never started again.
622
613
  */
623
614
  export declare class RunTimeoutError extends PipelexRequestError {
624
615
  readonly runId: string;
@@ -634,7 +625,8 @@ export declare class RunTimeoutError extends PipelexRequestError {
634
625
  * server-side — resume by `runId` (`getRunResult` / `waitForResult` on a
635
626
  * hosted deployment, or the `location` status resource when provided).
636
627
  *
637
- * Its verdict is `runtime` and retryable: the run is still going, and is resumed by its id.
628
+ * Its problem is `client.follow_failed`, naming the run: its `retry` is `outcome_unknown`, since
629
+ * the run exists and executing again would pay for a second one, and its step `read_run`.
638
630
  */
639
631
  export declare class RunStillRunningError extends PipelexRequestError {
640
632
  readonly runId: string;
@@ -651,11 +643,12 @@ export declare class RunStillRunningError extends PipelexRequestError {
651
643
  * Run polling is a hosted-API extension, not part of the MTHDS Protocol: the
652
644
  * open-source `pipelex-api` runner executes methods but has no run store, so
653
645
  * it 404s those routes; only a deployment that includes the platform block
654
- * (the Pipelex Hosted API) serves status/results. Distinguished from a genuine
655
- * run-not-found 404, which carries the server's structured error envelope.
646
+ * (the Pipelex Hosted API) serves status/results. A route the deployment lacks answers a `404`
647
+ * whose body is no problem document; a run the platform does not know answers a `404` problem
648
+ * document, `run.not_found`, which is an `ApiResponseError`.
656
649
  *
657
- * Its verdict is `config`, not retryable: the base URL points at a bare runner without the run
658
- * lifecycle.
650
+ * Its problem is `runtime.unsupported`, naming the durable run lifecycle as the capability the
651
+ * deployment lacks: the base URL points at a bare runner without it.
659
652
  */
660
653
  export declare class RunLifecycleUnavailableError extends PipelexRequestError {
661
654
  readonly apiUrl: string;
@@ -670,57 +663,52 @@ export declare class RunLifecycleUnavailableError extends PipelexRequestError {
670
663
  * The ceiling, `pageLimit` pages, sits far beyond any real catalog, run history or file list, so reaching it
671
664
  * is a server-side fault — an endpoint minting a fresh cursor forever — not a coverage limit the
672
665
  * caller can raise. Throwing beats returning, because a silently truncated list is exactly the bug
673
- * paging was introduced to remove. Its verdict is `runtime`, not retryable.
666
+ * paging was introduced to remove. Its problem is `client.response_unreadable`.
674
667
  */
675
668
  export declare class PagingNotTerminatingError extends PipelexRequestError {
676
669
  readonly pageLimit: number;
677
670
  constructor(message: string, pageLimit: number);
678
671
  }
679
672
  /**
680
- * The platform codes a refusal about a stored method or one of its versions carries in
681
- * `ApiResponseError.code`, beside the generic `not_found`, `conflict` and `validation_failed`:
673
+ * The registry codes a refusal about a stored method or one of its versions carries, beside the
674
+ * core codes every route may answer:
682
675
  *
683
- * - `method_update_conflict` (`409`): the draft moved since the token a `writeDraft` or a
684
- * `publishMethod` sent, so nothing was written or published. Read the method again and
685
- * decide whether to keep its draft or overwrite it with the fresh token.
686
- * - `method_being_deleted` (`409`): the method's erasure has started, on every route that
676
+ * - `pipelex.catalog.update_conflict` (`409`): the draft moved since the token a `writeDraft` or a
677
+ * `publishMethod` sent, so nothing was written or published. Read the method again and decide
678
+ * whether to keep its draft or overwrite it with the fresh token.
679
+ * - `pipelex.catalog.being_deleted` (`409`): the method's erasure has started, on every route that
687
680
  * addresses it.
688
- * - `method_not_published` (`409`): a bare `method_id` names the latest published version and
689
- * the method was never published. Publish it, or address its draft as `mt_…@draft`.
690
- * - `method_version_not_found` (`404`): `mt_…@<n>`, or `getMethodVersion`, names a version
691
- * the method never published. An unknown method is `not_found` instead.
692
- * - `organization_not_found` (`404`): the destination of a `copyMethod` is one the caller does
693
- * not belong to, one still being set up, or one that does not exist, answered alike so the
694
- * platform never says whether an organization exists. An unknown method is `not_found`.
695
- * - `method_copy_too_large` (`422`): a `copyMethod` past one of the copy's bounds on the stored
696
- * files it copies, which `problemDocument.limit` names (`MethodCopyLimit`).
697
- *
698
- * `code` stays a `string`, since the platform adds codes; this type names the ones a method
699
- * caller branches on. Each is `input` and not retryable by the fallback verdict.
700
- */
701
- export type MethodErrorCode = "method_update_conflict" | "method_being_deleted" | "method_not_published" | "method_version_not_found" | "organization_not_found" | "method_copy_too_large";
702
- /**
703
- * The platform code a refusal about a request's `Idempotency-Key` carries in
704
- * `ApiResponseError.code`, beside the generic `conflict`:
705
- *
706
- * - `idempotency_key_in_use` (`409`): an earlier request under the same key and the same body is
707
- * still being handled, or this one lost the key while it was handled, so nothing ran for this
708
- * one. `runtime` and retryable: wait a few seconds (the answer carries a `Retry-After` header,
709
- * which `ApiResponseError` does not expose) and send the same request again under the **same**
710
- * key, which is answered with the earlier request's
711
- * outcome once it is stored. A new key would run it a second time. On a `start`, its
712
- * `runMayHaveStarted` is false: this request started nothing.
713
- *
714
- * The key's other refusal carries the generic `conflict` (`409`, `input`, not retryable): the
715
- * key was used before with a different body, or is bound to a run that has since been deleted.
716
- * Either way the request is sent again under a new key, with the original body for the first.
717
- */
718
- export type IdempotencyErrorCode = "idempotency_key_in_use";
719
- /**
720
- * The `code` of an `errors[]` entry when `updateOrganizationBranding` refuses a logo. The entry's
721
- * `field` is the slot, `square_logo` or `wide_logo`, and its `detail` the sentence to show under
722
- * that slot. The refusal itself is a `422` `validation_failed` naming both slots' failures at
723
- * once, one entry per broken rule, and writes nothing:
681
+ * - `pipelex.catalog.not_published` (`409`): a bare `method_id` names the latest published version
682
+ * and the method was never published. Publish it, or address its draft as `mt_…@draft`.
683
+ * - `pipelex.catalog.not_found` (`404`): the method is not one of the organization's, or
684
+ * `mt_…@<n>`, or `getMethodVersion`, names a version the method never published.
685
+ * - `pipelex.org.not_found` (`404`): the destination of a `copyMethod` is one the caller does not
686
+ * belong to, one still being set up, or one that does not exist, answered alike so the platform
687
+ * never says whether an organization exists. An unknown method is `pipelex.catalog.not_found`.
688
+ * - `pipelex.catalog.copy_too_large` (`422`): a `copyMethod` past one of the copy's bounds on the
689
+ * stored files it copies, which the problem's `limit` member names (`MethodCopyLimit`).
690
+ *
691
+ * `code` stays a `string`, since the registry adds codes; this type names the ones a method caller
692
+ * branches on. Each has `domain` `input` and `retry` `no`.
693
+ */
694
+ export type MethodErrorCode = "pipelex.catalog.update_conflict" | "pipelex.catalog.being_deleted" | "pipelex.catalog.not_published" | "pipelex.catalog.not_found" | "pipelex.org.not_found" | "pipelex.catalog.copy_too_large";
695
+ /**
696
+ * The registry codes a refusal about a request's `Idempotency-Key` carries:
697
+ *
698
+ * - `request.idempotency_key_in_use` (`409`): an earlier request under the same key and the same
699
+ * body is still being handled, so nothing ran for this one. Its `retry` is `yes`: wait the
700
+ * problem's `retry_after` seconds (`ApiResponseError.retryAfter`) and send the same request
701
+ * again under the **same** key, which is answered with the earlier request's outcome once it is
702
+ * stored. A new key would run it a second time.
703
+ * - `request.idempotency_conflict` (`409`): the key was used before with a different body, or is
704
+ * bound to a run that has since been deleted. Its `retry` is `no`: the request is sent again
705
+ * under a new key, with the original body for the first.
706
+ */
707
+ export type IdempotencyErrorCode = "request.idempotency_key_in_use" | "request.idempotency_conflict";
708
+ /**
709
+ * The reason the platform gives a refused logo when `updateOrganizationBranding` refuses one. The
710
+ * refusal is one problem naming both slots' failures at once, one item of its `errors` per broken
711
+ * rule, and writes nothing:
724
712
  *
725
713
  * - `logo_not_an_upload`: the URI is neither a new upload of the organization nor the `uri` the
726
714
  * slot already holds: a run's or a method's file, a stale `branding/` copy, or the other slot's
@@ -748,200 +736,55 @@ export type IdempotencyErrorCode = "idempotency_key_in_use";
748
736
  * - `logo_too_small`: a raster square logo under 128 px on a side.
749
737
  * - `logo_not_wide`: a wide logo less than one and a half times as wide as it is tall.
750
738
  * - `logo_too_short`: a raster wide logo under 64 px tall.
751
- *
752
- * Two refusals of a logo URI come before any file is read and name the slot the same way, with
753
- * the platform's own code: `400` `invalid_storage_uri` for a URI that is not a storage URI, and
754
- * `403` `forbidden` for another organization's file. A colour's refusal names its key instead
755
- * (`colors.action`, `dark_colors.header`) with pydantic's code. `FieldError.code` stays a
756
- * `string`, since the platform adds codes.
757
739
  */
758
740
  export type LogoRefusalCode = "logo_not_an_upload" | "logo_not_found" | "logo_too_large" | "logo_type_not_accepted" | "logo_unreadable" | "logo_active_content" | "logo_not_square" | "logo_too_small" | "logo_not_wide" | "logo_too_short";
759
- /**
760
- * The last constructor argument of `ApiResponseError`: the error's `cause`, the hosted problem
761
- * document's typed members, the decoded document whole, the answer's headers, and whether the
762
- * request that met the answer may create a run.
763
- */
741
+ /** What an `ApiResponseError` is built from beside its message and the answer's facts. */
764
742
  export interface ApiResponseErrorOptions {
765
743
  cause?: unknown;
766
- /** The hosted problem document's typed members, as the client parsed them. */
767
- details?: ProblemDetails;
768
- problemDocument?: Record<string, unknown>;
769
744
  /**
770
- * The answer's headers, which the standard's reading takes a `Retry-After` from (see
771
- * `ApiResponseError.problem`). The client passes them; a consumer building the error by hand
772
- * may leave them out.
745
+ * The answer read as its problem. The client passes the one it read (`readHostedAnswer`); a
746
+ * consumer building the error by hand may leave it out, and the error then reads the answer
747
+ * itself, as the client would.
748
+ */
749
+ problem?: Problem;
750
+ /**
751
+ * The answer's headers, which a `Retry-After` and an `X-Request-ID` are read from. The client
752
+ * passes them; a consumer building the error by hand may leave them out.
773
753
  */
774
754
  headers?: AnswerHeaders;
775
755
  /**
776
- * The request was a `start` or an `execute`, so the answer is read for whether it may have
777
- * started a run (see `ApiResponseError.runMayHaveStarted`). The client sets it on those two
778
- * routes alone; a consumer building the error by hand sets it to get the verdict the client
779
- * would give.
756
+ * The request was a `start` or an `execute`, which creates a run, so an answer that is no
757
+ * problem document is read for whether the run may exist (`readHostedAnswer`). The client sets
758
+ * it on those two routes alone; it only matters when `problem` is left out.
780
759
  */
781
760
  mayStartRun?: boolean;
782
761
  }
783
762
  /**
784
763
  * A response that DID come back from the API and that the SDK cannot hand back as a result: a
785
- * non-2xx refusal, with its problem document parsed, or a 2xx answer the SDK could not read —
786
- * a body that is not JSON, JSON that is not the object the route answers, or a stored method
787
- * whose `python` field is not the serialized file list. The second carries the answer's status
788
- * and raw text, no hosted problem member, what made it unreadable as `cause` (the parse failure,
789
- * or `mthds`'s refusal of the `python` field), the verdict the fallback gives a 2xx (`runtime`,
790
- * not retryable), and as `problem` the standard's reading of such an answer:
791
- * `client.response_unreadable`, or `client.outcome_unknown` on a request that may create a run.
792
- *
793
- * Every error the hosted API answers is an RFC 9457 `application/problem+json` document, and
794
- * this error carries its members as typed fields, each `undefined` when the document did not
795
- * carry it (a member of the wrong type reads as absent rather than as a wrong value, and the
796
- * nested members `providerMetadata`, `migration`, `validationErrors` and `errors` are checked
797
- * field by field as a failed run's stored report is) — except the verdict, which is always
798
- * decided:
799
- *
800
- * - **The verdict.** `errorDomain` says who can fix the failure — `input` (the caller),
801
- * `config` (a configuration change), `runtime` (nobody beforehand) — and `retryable` whether
802
- * asking again can succeed. Each is the document's member when the server sent a valid one,
803
- * and otherwise the SDK's fallback, read from the status, the platform `code` and whether the
804
- * body names what it refused. A runner often sends `error_domain` without `retryable`, and
805
- * then the domain it sent decides `retryable`: `input` and `config` are not retryable, as a
806
- * stored report that says nothing is not, since the caller or the environment must change,
807
- * while `runtime` takes the fallback's. Nothing on the error says which a value came from:
808
- * `problemDocument` keeps what the server sent.
809
- * - **A run that may have started.** On a `start` or an `execute`, `runMayHaveStarted` says
810
- * whether the answer leaves a run possibly started without its id reaching the caller: any
811
- * `2xx` the SDK could not read, a `408`, and every `5xx` but a `501` and the platform's `503`
812
- * coded `pipeline_start_unavailable`, which says the runner was never reached. Then
813
- * `retryable` is false, whatever the server sent: asking again could start a second run. A
814
- * runner's own failure of a blocking execute reads the same, since the SDK cannot tell a run
815
- * that ended from one that goes on, and its `retryable` stays readable on `problemDocument`.
816
- * On every other route it is false.
817
- * - **The branch fields.** `errorDomain`, and `type`, the stable URI naming the error class.
818
- * Branch on these, never on the HTTP status or on the wording of a message; they are the
819
- * fields that mean the same on both surfaces.
820
- * - **The native codes.** `code` is the platform's own closed code (`conflict`, `not_found`,
821
- * `pipelex_api_key_limit_reached`, …; `MethodErrorCode` names the method ones and
822
- * `IdempotencyErrorCode` the idempotency key's) and `errorType` the runner's open exception
823
- * class name. Each is finer than `errorDomain` and
824
- * specific to the surface that emits it, and a client of that surface may branch on it: the
825
- * platform's `type` is derived from its `code` one to one
826
- * (`https://pipelex.com/errors/<code>`), so the two read the same answer. A problem the
827
- * platform relays from the runner carries the runner's `type` and `errorType` and no `code`.
828
- * - **For a person.** `title` is the stable label of the error class, `serverMessage` the
829
- * per-occurrence `detail`, `userAction` the advised next step, and `errorCategory`, `model`,
830
- * `provider` and `providerMetadata` describe an inference failure.
831
- * - **For support.** `requestId` correlates the response with the server's logs; it is read
832
- * from the body, or from the `X-Request-ID` response header when the body has none.
833
- * `instance` is the occurrence's URN or request path.
834
- * - **Per-item failures.** `errors` is the platform's field-level list (`field`, `code`,
835
- * `detail`), and `validationErrors` the structured diagnostics of a bundle that failed
836
- * validation.
837
- * - **The standard's reading.** `problem` is the same answer read as the MTHDS standard reads
838
- * it, the problem `mthds`'s own `ApiResponseError` carries: the body itself when it is a core
839
- * problem document, and otherwise the problem its status reads as (`readAnswer` in
840
- * `mthds/protocol`), except on a request that may create a run, where `runMayHaveStarted`
841
- * decides: `client.outcome_unknown` for every answer that leaves a run possibly started, a core
842
- * problem document's body included. Branch on `problem.code` to handle this SDK's errors and the
843
- * standard client's alike. The hosted plane's problem documents predate the core registry, so
844
- * for them `problem` says little; the members above are read from the hosted document as they
845
- * always were, and those the standard names its own way do not collide with it: `code` is the
846
- * platform's code beside the registry's `problem.code`, and `errors` the platform's field
847
- * errors beside the problem items of `problem.errors`.
848
- *
849
- * `problemDocument` is the decoded document whole, so a member this SDK does not name stays
850
- * reachable without re-parsing `responseBody`, which is the raw text; it is `undefined` when
851
- * the body was not a JSON object.
852
- *
853
- * The error is a `PipelineRequestError`, as every error of this SDK is, rather than the
854
- * standard's `ProblemError`: a `ProblemError`'s `code` is the registry's and its message the
855
- * problem's sentence, while this error's `code` is the platform's and its message names the
856
- * route and the hosted document's `detail`, so it carries the standard's reading as `problem`
857
- * instead.
764
+ * non-2xx refusal, a body that arrived and could not be decoded, or a 2xx answer the SDK could not
765
+ * read — a body that is not JSON, JSON that is not the object the route answers, or a stored
766
+ * method whose `python` field is not the serialized file list.
767
+ *
768
+ * Its `problem` is the answer read as a problem (`readHostedAnswer`): the body itself when it is a
769
+ * problem document, as the hosted API answers every refusal, its `pipelex.*` code and any member
770
+ * the standard does not name kept; and otherwise the reading of the edge's bare answers by its
771
+ * status, `client.outcome_unknown` among them for a start or an execute the gateway cut off. Every
772
+ * getter of `ProblemError` reads it: branch on `code`, never on the HTTP status or the wording of
773
+ * a message. `retryAfter` is the problem's `retry_after`, which the `Retry-After` header fills when
774
+ * the problem invites a retry and gives none, and `requestId` the problem's `request_id`, else the
775
+ * answer's `X-Request-ID` header, the id to hand to support.
776
+ *
777
+ * `status` is the answer's HTTP status whatever the problem's own `status` says, `statusText` its
778
+ * reason phrase and `responseBody` its raw text, so a member this SDK does not name stays
779
+ * reachable without re-reading the body.
858
780
  */
859
781
  export declare class ApiResponseError extends PipelexRequestError {
860
782
  readonly apiUrl: string;
861
783
  readonly status: number;
862
784
  readonly statusText: string;
863
785
  readonly responseBody: string;
864
- readonly errorType: string | undefined;
865
- readonly serverMessage: string | undefined;
866
- /**
867
- * The platform's native code — a closed set (`conflict`, `not_found`, `run_not_found`,
868
- * `pipelex_api_key_limit_reached`, …), one-to-one with `type`; `MethodErrorCode` names the
869
- * ones about a stored method and its versions, and `IdempotencyErrorCode` the one about a
870
- * request's idempotency key. Finer than `errorDomain` and specific to the
871
- * platform: a runner's problem carries `errorType` instead. `undefined` for a body that
872
- * carries no `code`.
873
- */
874
- readonly code: string | undefined;
875
- /**
876
- * RFC 9457 `type`: the stable URI naming the error class. With `errorDomain`, the field a
877
- * machine consumer branches on — the same class carries the same URI on every occurrence.
878
- */
879
- readonly type: string | undefined;
880
- /** RFC 9457 `title`: the short human label of the error class. */
881
- readonly title: string | undefined;
882
- /** RFC 9457 `instance`: the occurrence — the request path, or a request URN. */
883
- readonly instance: string | undefined;
884
- /**
885
- * The request's correlation id — the body's `request_id`, or the `X-Request-ID` response
886
- * header when the body carries none. The id to hand to support: it finds the server's log
887
- * lines for this request.
888
- */
889
- readonly requestId: string | undefined;
890
- /**
891
- * The body's `error_category`: the finer classification of an inference failure — known
892
- * values `transient`, `configuration`, `content`, `capacity`, `ambiguous`, `unknown`.
893
- */
894
- readonly errorCategory: string | undefined;
895
- /** The body's `user_action`: what the caller should do next, when the server can say. */
896
- readonly userAction: UserAction | undefined;
897
- /** The body's `model`: the model an inference failure used. */
898
- readonly model: string | undefined;
899
- /** The body's `provider`: the provider an inference failure reached. */
900
- readonly provider: string | undefined;
901
- /**
902
- * The body's `provider_metadata`: what the provider's SDK said. On the hosted API it comes
903
- * from the runner's problem document, which the hosted runner renders under its STRICT
904
- * disclosure, so it keeps only `status_code` and `retry_after_seconds`; a runner that
905
- * discloses errors VERBOSE, as a self-hosted one does when `ERROR_DISCLOSURE` is unset, sends
906
- * it whole, the provider's raw text included.
907
- */
908
- readonly providerMetadata: ProviderErrorMetadata | undefined;
909
- /** The body's `migration`: a pending configuration migration that explains the failure. */
910
- readonly migration: MigrationErrorBlock | undefined;
911
- /**
912
- * The platform's field-level `errors[]` — one item per offending request field. A refused
913
- * branding write names the logo slot or the colour key each entry is about in its `field`,
914
- * with a `LogoRefusalCode` for a logo the platform measured.
915
- */
916
- readonly errors: FieldError[] | undefined;
917
- /**
918
- * The decoded problem document whole — every member, named or not, such as a failed run's
919
- * `run_status` and `error` or a member a newer server adds. `undefined` when the body was not
920
- * a JSON object.
921
- */
922
- readonly problemDocument: Record<string, unknown> | undefined;
923
- /**
924
- * Structured per-error diagnostics on a problem body that carries a top-level
925
- * `validation_errors[]` — the 422 a **run route** (`execute`, `start`) answers when the
926
- * runner refuses the method for its validation errors.
927
- *
928
- * Everywhere else an invalid bundle is a produced verdict, not an `ApiResponseError`:
929
- * `POST /v1/validate` answers it with a **200** `PipelexInvalidReport`, and the crate
930
- * routes with a **200** `CrateInvalidReport`, whose `validation_errors[]` the caller
931
- * reads off the returned value. This field is `undefined` for any error that carries no
932
- * per-error list (auth, transport, a request-shape 422, the 422 `pipe-io` answers for a
933
- * pipe selection it refuses). A consumer must NOT assume a given `error_type` implies a
934
- * populated list — fall back to `serverMessage` when this is empty.
935
- */
936
- readonly validationErrors: ValidationErrorItem[] | undefined;
937
- /**
938
- * The answer read as the MTHDS standard reads it, the problem `mthds`'s own client carries,
939
- * agreeing with `runMayHaveStarted`: `client.outcome_unknown` where a run may have started,
940
- * whatever the body, and where none started the body when it is a core problem document,
941
- * otherwise the reading of an answer to a request that creates no run.
942
- * Built from the constructor's arguments, so an error a consumer builds by hand carries the
943
- * reading the client would give it.
944
- */
945
- readonly problem: Problem;
946
- constructor(message: string, apiUrl: string, status: number, statusText: string, responseBody: string, errorType: string | undefined, serverMessage: string | undefined, validationErrors: ValidationErrorItem[] | undefined, code: string | undefined, options?: ApiResponseErrorOptions);
786
+ private readonly requestIdHeader;
787
+ constructor(message: string, apiUrl: string, status: number, statusText: string, responseBody: string, options?: ApiResponseErrorOptions);
788
+ /** The request's id: the problem's `request_id`, else the answer's `X-Request-ID` header. */
789
+ get requestId(): string | undefined;
947
790
  }