@pipelex/sdk 0.32.0 → 0.34.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.
- package/README.md +40 -5
- package/dist/artifacts.js +23 -9
- package/dist/artifacts.js.map +1 -1
- package/dist/cli/args.d.ts +41 -0
- package/dist/cli/args.js +96 -0
- package/dist/cli/args.js.map +1 -0
- package/dist/cli/bundle.d.ts +45 -0
- package/dist/cli/bundle.js +148 -0
- package/dist/cli/bundle.js.map +1 -0
- package/dist/cli/environment.d.ts +36 -0
- package/dist/cli/environment.js +72 -0
- package/dist/cli/environment.js.map +1 -0
- package/dist/cli/help.d.ts +4 -0
- package/dist/cli/help.js +56 -0
- package/dist/cli/help.js.map +1 -0
- package/dist/cli/inputs.d.ts +13 -0
- package/dist/cli/inputs.js +70 -0
- package/dist/cli/inputs.js.map +1 -0
- package/dist/cli/io.d.ts +79 -0
- package/dist/cli/io.js +96 -0
- package/dist/cli/io.js.map +1 -0
- package/dist/cli/main.d.ts +18 -0
- package/dist/cli/main.js +58 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/cli/method.d.ts +56 -0
- package/dist/cli/method.js +108 -0
- package/dist/cli/method.js.map +1 -0
- package/dist/cli/present.d.ts +43 -0
- package/dist/cli/present.js +191 -0
- package/dist/cli/present.js.map +1 -0
- package/dist/cli/run.d.ts +17 -0
- package/dist/cli/run.js +290 -0
- package/dist/cli/run.js.map +1 -0
- package/dist/cli/script.d.ts +23 -0
- package/dist/cli/script.js +212 -0
- package/dist/cli/script.js.map +1 -0
- package/dist/cli/source.d.ts +49 -0
- package/dist/cli/source.js +71 -0
- package/dist/cli/source.js.map +1 -0
- package/dist/cli.d.ts +10 -0
- package/dist/cli.js +65 -0
- package/dist/cli.js.map +1 -0
- package/dist/client.d.ts +125 -17
- package/dist/client.js +383 -109
- package/dist/client.js.map +1 -1
- package/dist/codegen-check.d.ts +9 -0
- package/dist/codegen-check.js +12 -6
- package/dist/codegen-check.js.map +1 -1
- package/dist/error-models.d.ts +60 -2
- package/dist/error-models.js +169 -3
- package/dist/error-models.js.map +1 -1
- package/dist/error-verdicts.d.ts +34 -0
- package/dist/error-verdicts.js +69 -0
- package/dist/error-verdicts.js.map +1 -0
- package/dist/errors.d.ts +250 -48
- package/dist/errors.js +330 -64
- package/dist/errors.js.map +1 -1
- package/dist/hooks/validate-client.d.ts +3 -3
- package/dist/hooks/validate-client.js +3 -3
- package/dist/index.d.ts +4 -4
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/prepare-inputs.d.ts +6 -0
- package/dist/prepare-inputs.js +46 -14
- package/dist/prepare-inputs.js.map +1 -1
- package/dist/runs.d.ts +28 -1
- package/dist/runs.js +2 -1
- package/dist/runs.js.map +1 -1
- package/dist/upload-grant.d.ts +15 -10
- package/dist/upload-grant.js +36 -17
- package/dist/upload-grant.js.map +1 -1
- package/dist/upload.d.ts +6 -0
- package/dist/upload.js +25 -7
- package/dist/upload.js.map +1 -1
- package/dist/user-agent.d.ts +3 -2
- package/dist/user-agent.js +3 -2
- package/dist/user-agent.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/docs/architecture.md +15 -9
- package/docs/artifact-download.md +3 -3
- package/docs/cli.md +123 -0
- package/docs/client-identification.md +1 -1
- package/docs/errors.md +96 -11
- package/docs/input-preparation.md +16 -8
- package/docs/run-results.md +20 -0
- package/package.json +5 -1
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The method as each route names it, and the one pipe I/O call that checks it.
|
|
3
|
+
*
|
|
4
|
+
* A bundle read from disk travels to the pipe I/O route as `files`, each file under its name in the
|
|
5
|
+
* bundle, and to the run as `mthds_contents`, in the same order. An address travels as
|
|
6
|
+
* `method_ref` and a catalog id as `method_id`, both resolved by the server.
|
|
7
|
+
*/
|
|
8
|
+
import { CommandError, EXIT_FAILED, untilInterrupted } from "./io.js";
|
|
9
|
+
import { loadFailureLines, METHOD_DOES_NOT_LOAD_SENTENCE } from "./present.js";
|
|
10
|
+
export function crateSelector(source) {
|
|
11
|
+
switch (source.kind) {
|
|
12
|
+
case "bundle":
|
|
13
|
+
return { files: source.files.map((file) => ({ content: file.content, source: file.name })) };
|
|
14
|
+
case "address":
|
|
15
|
+
return { method_ref: source.methodRef };
|
|
16
|
+
case "catalog":
|
|
17
|
+
return { method_id: source.methodId };
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/** The method as the run routes name it. */
|
|
21
|
+
export function runSelector(source) {
|
|
22
|
+
switch (source.kind) {
|
|
23
|
+
case "bundle":
|
|
24
|
+
return { mthds_contents: source.files.map((file) => file.content) };
|
|
25
|
+
case "address":
|
|
26
|
+
return { method_ref: source.methodRef };
|
|
27
|
+
case "catalog":
|
|
28
|
+
return { method_id: source.methodId };
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Ask `POST /v1/pipe-io` for the pipe the method and `--pipe` select, which spends no inference:
|
|
33
|
+
* the same selection the run's input preparation makes.
|
|
34
|
+
*
|
|
35
|
+
* @throws {CommandError} When the method does not load, or the answer does not describe the pipe
|
|
36
|
+
* it selected. A refusal of the request itself propagates as the SDK's `ApiResponseError`.
|
|
37
|
+
* @throws {Interrupted} When the person interrupts the wait.
|
|
38
|
+
*/
|
|
39
|
+
export async function describePipe(client, source, pipe, interrupt) {
|
|
40
|
+
const request = {
|
|
41
|
+
...crateSelector(source),
|
|
42
|
+
...(pipe === undefined ? {} : { pipe_ref: pipe }),
|
|
43
|
+
};
|
|
44
|
+
const answer = await untilInterrupted(() => client.pipeIo(request), interrupt);
|
|
45
|
+
if (!isPlainObject(answer) || typeof answer.is_valid !== "boolean") {
|
|
46
|
+
throw new CommandError("the API's pipe I/O answer says neither that the method loads nor why it does not.", {
|
|
47
|
+
exitCode: EXIT_FAILED,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
if (!answer.is_valid) {
|
|
51
|
+
throw new CommandError(METHOD_DOES_NOT_LOAD_SENTENCE, {
|
|
52
|
+
exitCode: EXIT_FAILED,
|
|
53
|
+
details: loadFailureLines(answer.validation_errors, answer.message),
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
const report = answer;
|
|
57
|
+
const pipeRef = report.pipe_ref;
|
|
58
|
+
const inputForm = report.input_form;
|
|
59
|
+
if (typeof pipeRef !== "string" ||
|
|
60
|
+
!isPlainObject(inputForm) ||
|
|
61
|
+
!isPlainObject(inputForm[pipeRef])) {
|
|
62
|
+
throw new CommandError("the API's pipe I/O answer does not describe the pipe it selected.", {
|
|
63
|
+
exitCode: EXIT_FAILED,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
return { report, pipeRef, descriptor: inputForm[pipeRef] };
|
|
67
|
+
}
|
|
68
|
+
function isPlainObject(value) {
|
|
69
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=source.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"source.js","sourceRoot":"","sources":["../../src/cli/source.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* The `pipelex-sdk` executable, which `package.json` declares as the package's one `bin`, so that
|
|
4
|
+
* `npx @pipelex/sdk run …` runs it. It hands the command the real process — its arguments, its
|
|
5
|
+
* environment, its streams and Ctrl-C — and exits with the command's code (`docs/cli.md`).
|
|
6
|
+
*
|
|
7
|
+
* It uses no top-level `await`, as no module of `dist/` does, so that the package stays loadable
|
|
8
|
+
* through `require(ESM)` (`docs/architecture.md`, "Module format & packaging").
|
|
9
|
+
*/
|
|
10
|
+
export {};
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* The `pipelex-sdk` executable, which `package.json` declares as the package's one `bin`, so that
|
|
4
|
+
* `npx @pipelex/sdk run …` runs it. It hands the command the real process — its arguments, its
|
|
5
|
+
* environment, its streams and Ctrl-C — and exits with the command's code (`docs/cli.md`).
|
|
6
|
+
*
|
|
7
|
+
* It uses no top-level `await`, as no module of `dist/` does, so that the package stays loadable
|
|
8
|
+
* through `require(ESM)` (`docs/architecture.md`, "Module format & packaging").
|
|
9
|
+
*/
|
|
10
|
+
import process from "node:process";
|
|
11
|
+
import { EXIT_INTERRUPTED, ignoreClosedPipe } from "./cli/io.js";
|
|
12
|
+
import { runCommand } from "./cli/main.js";
|
|
13
|
+
const interrupt = new AbortController();
|
|
14
|
+
// Once: a second Ctrl-C finds no handler and ends the process the default way.
|
|
15
|
+
process.once("SIGINT", () => interrupt.abort());
|
|
16
|
+
// A reader that stops early (`| head`, `2>&1 | head -1`) closes the pipe on either stream.
|
|
17
|
+
ignoreClosedPipe(process.stdout);
|
|
18
|
+
ignoreClosedPipe(process.stderr);
|
|
19
|
+
void runCommand(process.argv.slice(2), {
|
|
20
|
+
env: process.env,
|
|
21
|
+
readStdin: async () => {
|
|
22
|
+
const chunks = [];
|
|
23
|
+
for await (const chunk of process.stdin)
|
|
24
|
+
chunks.push(chunk);
|
|
25
|
+
return Buffer.concat(chunks);
|
|
26
|
+
},
|
|
27
|
+
writeStdout: (text) => {
|
|
28
|
+
process.stdout.write(text);
|
|
29
|
+
},
|
|
30
|
+
writeStderr: (text) => {
|
|
31
|
+
process.stderr.write(text);
|
|
32
|
+
},
|
|
33
|
+
interrupt: interrupt.signal,
|
|
34
|
+
}).then(exitWhenFlushed);
|
|
35
|
+
/**
|
|
36
|
+
* Exit once both streams have flushed, rather than when the event loop empties: a request the
|
|
37
|
+
* command stopped waiting for on Ctrl-C, such as the start of a run, would otherwise hold the
|
|
38
|
+
* process open until the API answers it.
|
|
39
|
+
*
|
|
40
|
+
* After Ctrl-C, the process ends by the signal itself rather than by `process.exit(130)`, which a
|
|
41
|
+
* POSIX shell reports as the same status, 130: Node's exit waits for its worker threads, and one
|
|
42
|
+
* can be blocked for good in a read the command stopped waiting for, such as `--inputs` naming a
|
|
43
|
+
* named pipe no one writes to, or `/dev/stdin` on a terminal. Ending by the signal also tells a
|
|
44
|
+
* calling shell loop that the person interrupted. Windows has no such signal to end by, and exits
|
|
45
|
+
* with 130.
|
|
46
|
+
*/
|
|
47
|
+
async function exitWhenFlushed(code) {
|
|
48
|
+
await flush(process.stdout);
|
|
49
|
+
await flush(process.stderr);
|
|
50
|
+
if (code === EXIT_INTERRUPTED && interrupt.signal.aborted && process.platform !== "win32") {
|
|
51
|
+
// The once-only handler is gone, so SIGINT has its default action again: ending the process.
|
|
52
|
+
process.kill(process.pid, "SIGINT");
|
|
53
|
+
}
|
|
54
|
+
process.exit(code);
|
|
55
|
+
}
|
|
56
|
+
function flush(stream) {
|
|
57
|
+
return new Promise((resolve) => {
|
|
58
|
+
if (stream.destroyed || !stream.writable) {
|
|
59
|
+
resolve();
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
stream.write("", () => resolve());
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;GAOG;AAEH,OAAO,OAAO,MAAM,cAAc,CAAC;AAGnC,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3C,MAAM,SAAS,GAAG,IAAI,eAAe,EAAE,CAAC;AACxC,+EAA+E;AAC/E,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC;AAEhD,2FAA2F;AAC3F,gBAAgB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;AACjC,gBAAgB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;AAEjC,KAAK,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;IACrC,GAAG,EAAE,OAAO,CAAC,GAAG;IAChB,SAAS,EAAE,KAAK,IAAI,EAAE;QACpB,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,OAAO,CAAC,KAAK;YAAE,MAAM,CAAC,IAAI,CAAC,KAAe,CAAC,CAAC;QACtE,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC/B,CAAC;IACD,WAAW,EAAE,CAAC,IAAI,EAAE,EAAE;QACpB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;IACD,WAAW,EAAE,CAAC,IAAI,EAAE,EAAE;QACpB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;IACD,SAAS,EAAE,SAAS,CAAC,MAAM;CAC5B,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;AAEzB;;;;;;;;;;;GAWG;AACH,KAAK,UAAU,eAAe,CAAC,IAAY;IACzC,MAAM,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5B,MAAM,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5B,IAAI,IAAI,KAAK,gBAAgB,IAAI,SAAS,CAAC,MAAM,CAAC,OAAO,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QAC1F,6FAA6F;QAC7F,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IACtC,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACrB,CAAC;AAED,SAAS,KAAK,CAAC,MAAgB;IAC7B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,IAAI,MAAM,CAAC,SAAS,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;YACzC,OAAO,EAAE,CAAC;YACV,OAAO;QACT,CAAC;QACD,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;AACL,CAAC"}
|
package/dist/client.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { MTHDSProtocol, ModelCategory, ModelDeck, RunOptions, StartOptions, VersionInfo } from "mthds/protocol";
|
|
2
2
|
import type { CodegenRequest, CodegenResponse, DictPipeOutput, FormatResponse, LintResponse, MthdsFileItem, PipeIORequest, PipeIOResponse, PipelexRunResultStart, PipelexValidationResult, ResolveRequest, ResolveResponse, ValidateMethodSelector } from "./models.js";
|
|
3
|
-
import { type GetRunResultOptions, type RunRead, type RunResults, type RunResultState, type WaitForResultOptions } from "./runs.js";
|
|
3
|
+
import { type GetRunResultOptions, type RunRead, type RunResults, type RunResultState, type StartAndWaitForResultOptions, type WaitForResultOptions } from "./runs.js";
|
|
4
4
|
import type { BillingPortalResponse, ChangePlanResponse, CheckoutResponse, InvoiceView, Membership, MembershipsResponse, ListMethodsQuery, MethodData, MethodDeletionAccepted, MethodPage, MethodSummary, MethodWriteInput, OnboardingSubmission, PipelexApiKeyCreated, PipelexApiKeyList, ListRunsQuery, RunHistoryItem, RunDetail, RunPage, PlanView, ResolvedStorageUrl, SubscriptionResponse, UpdateRunInput, UploadGrant, UploadGrantInput, UploadInput, UploadedFile, UserProfile } from "./product-models.js";
|
|
5
5
|
import type { AppInfo } from "./user-agent.js";
|
|
6
6
|
import type { UploadableAsset, UploadFileOptions, UploadRecord } from "./upload.js";
|
|
@@ -120,7 +120,8 @@ export interface PipelexApiClientOptions {
|
|
|
120
120
|
* `{ name: "acme-invoicer", version: "1.4.0" }` →
|
|
121
121
|
* `acme-invoicer/1.4.0 pipelex-sdk-js/<v> node/<v> (<os>; <arch>)`. Validated at
|
|
122
122
|
* construction: a field that is not an RFC 9110 token throws a `TypeError`. See
|
|
123
|
-
* the
|
|
123
|
+
* the spec `conformance/specs/client-identification.md`, in the `conformance` repository
|
|
124
|
+
* beside the specs' tests.
|
|
124
125
|
*/
|
|
125
126
|
appInfo?: AppInfo;
|
|
126
127
|
}
|
|
@@ -155,14 +156,6 @@ export declare class PipelexApiClient implements MTHDSProtocol<DictPipeOutput> {
|
|
|
155
156
|
* resolved absolute URL.
|
|
156
157
|
*/
|
|
157
158
|
private requestRaw;
|
|
158
|
-
/**
|
|
159
|
-
* Issue a request and parse the JSON body, throwing a plain `Error` on a non-2xx
|
|
160
|
-
* response. Used only by `health` — the origin-level liveness probe, which sits
|
|
161
|
-
* outside `/v1` and outside the RFC 7807 error taxonomy the `/v1` routes share.
|
|
162
|
-
* Every `/v1` route goes through a helper that maps its problem body to the typed
|
|
163
|
-
* `ApiResponseError` instead.
|
|
164
|
-
*/
|
|
165
|
-
private requestJson;
|
|
166
159
|
/**
|
|
167
160
|
* Issue a Pipelex-product request (`/v1/me`, `/v1/methods`, `/v1/billing/*`,
|
|
168
161
|
* …) and parse its JSON body, mapping a non-2xx response to the typed
|
|
@@ -172,7 +165,65 @@ export declare class PipelexApiClient implements MTHDSProtocol<DictPipeOutput> {
|
|
|
172
165
|
* timeout, not the blocking-execute ceiling.
|
|
173
166
|
*/
|
|
174
167
|
private requestProduct;
|
|
168
|
+
/**
|
|
169
|
+
* A product request whose answer is an object the SDK or its caller reads before anything else
|
|
170
|
+
* — a bulk resolution's `items`, a run record's `error`, an upload grant's `url`. Unlike
|
|
171
|
+
* `requestProduct`, an empty
|
|
172
|
+
* 2xx is no answer here: it and a body that is not a JSON object throw the `ApiResponseError`
|
|
173
|
+
* of an answer the SDK cannot read (see `readObjectAnswerAt`).
|
|
174
|
+
*/
|
|
175
|
+
private requestProductObject;
|
|
176
|
+
/**
|
|
177
|
+
* A methods-catalog route answering one stored method (`getMethod`, `createMethod`,
|
|
178
|
+
* `updateMethod`), parsed into the public shape. A stored `mthds` that is neither a string nor
|
|
179
|
+
* absent (`null` stays "no source", which `getMethodClosure` reports), and a stored `python`
|
|
180
|
+
* the SDK cannot parse, are an answer it cannot read, so each throws an `ApiResponseError` built
|
|
181
|
+
* from that answer, the latter with `mthds`'s refusal as `cause`: `runtime`, not retryable,
|
|
182
|
+
* since no change to the call fixes it.
|
|
183
|
+
*/
|
|
184
|
+
private requestMethodData;
|
|
185
|
+
/**
|
|
186
|
+
* One page of a cursor-paged product route (`listMethods`, `listRuns`), read as the platform
|
|
187
|
+
* always serializes it: `items` an array, `next_cursor` a string or `null`. A page breaking
|
|
188
|
+
* either is an answer the SDK cannot read, so it throws the `ApiResponseError` `unreadableAnswer`
|
|
189
|
+
* builds, `runtime` and not retryable, rather than handing the iterators a page they cannot
|
|
190
|
+
* walk: `items` that is not iterable, or a missing cursor that is neither the end nor a next
|
|
191
|
+
* page, which `iterateRuns` would follow forever.
|
|
192
|
+
*/
|
|
193
|
+
private requestPage;
|
|
194
|
+
/** Issue a product request and return its 2xx answer, a non-2xx thrown as `ApiResponseError`. */
|
|
195
|
+
private requestProductAnswer;
|
|
175
196
|
private throwApiResponseError;
|
|
197
|
+
/** The JSON body of a `/v1` route's 2xx answer; see `readAnswerAt`. */
|
|
198
|
+
private readAnswer;
|
|
199
|
+
/** The JSON object body of a `/v1` route's 2xx answer; see `readObjectAnswerAt`. */
|
|
200
|
+
private readObjectAnswer;
|
|
201
|
+
/**
|
|
202
|
+
* The JSON body of a 2xx answer, naming the route by its `path` from the origin as a refusal
|
|
203
|
+
* does. A body that is not UTF-8, or not JSON, an empty one included, is an answer the SDK
|
|
204
|
+
* cannot read, so it throws the `ApiResponseError` `unreadableAnswer` builds, with the parse
|
|
205
|
+
* failure as `cause`.
|
|
206
|
+
* The one place a success body is parsed.
|
|
207
|
+
*/
|
|
208
|
+
private readAnswerAt;
|
|
209
|
+
/**
|
|
210
|
+
* The JSON body of a 2xx answer from a route that answers an object, read as `readAnswerAt`
|
|
211
|
+
* reads it. A body that is JSON but not an object — `null`, a number, a string, an array — is
|
|
212
|
+
* an answer the SDK cannot read either, and throws the same `ApiResponseError`, with no `cause`.
|
|
213
|
+
*/
|
|
214
|
+
private readObjectAnswerAt;
|
|
215
|
+
/**
|
|
216
|
+
* The `ApiResponseError` of a 2xx answer the SDK cannot read, its message
|
|
217
|
+
* `API <method> <path> answered <status> with <what>`: the answer's status, its raw text as
|
|
218
|
+
* `responseBody`, no problem member but the `X-Request-ID` header, the failure that made it
|
|
219
|
+
* unreadable as `cause`, and the verdict the fallback gives a 2xx, `runtime` and not retryable.
|
|
220
|
+
*/
|
|
221
|
+
private unreadableAnswer;
|
|
222
|
+
/**
|
|
223
|
+
* Throw the `ApiResponseError` of a non-2xx answer, naming the route by its `path` from the
|
|
224
|
+
* origin (`/v1/...`, or `/health` for the liveness probe).
|
|
225
|
+
*/
|
|
226
|
+
private throwApiResponseErrorAt;
|
|
176
227
|
/**
|
|
177
228
|
* Translate a "route absent" 404 (a bare pipelex-api with no platform block)
|
|
178
229
|
* into a clear `RunLifecycleUnavailableError`. The platform's own 404s (run
|
|
@@ -187,6 +238,16 @@ export declare class PipelexApiClient implements MTHDSProtocol<DictPipeOutput> {
|
|
|
187
238
|
* hints) beats a generic parse failure on an unexpected body shape.
|
|
188
239
|
*/
|
|
189
240
|
private throwIfExecuteDegraded;
|
|
241
|
+
/**
|
|
242
|
+
* The origin-level liveness probe — `GET /health`, which sits at the origin, NOT under the
|
|
243
|
+
* `/v1` prefix. A bare runner serves it; a hosted origin answers `/v1/health` instead, so
|
|
244
|
+
* there this throws.
|
|
245
|
+
*
|
|
246
|
+
* It goes through the same transport as every route: an unreachable origin is an
|
|
247
|
+
* `ApiUnreachableError`, and a non-2xx answer an `ApiResponseError` whose verdict the SDK's
|
|
248
|
+
* fallback reads from the status, since the probe answers no problem document. So is a 2xx
|
|
249
|
+
* whose body is not a JSON object, such as a gateway's HTML page: `runtime`, not retryable.
|
|
250
|
+
*/
|
|
190
251
|
health(): Promise<Record<string, unknown>>;
|
|
191
252
|
/**
|
|
192
253
|
* Execute a method synchronously and wait for its completion —
|
|
@@ -442,8 +503,10 @@ export declare class PipelexApiClient implements MTHDSProtocol<DictPipeOutput> {
|
|
|
442
503
|
* Self-healing: a finished-but-unrecorded run resolves to its true terminal
|
|
443
504
|
* status on read. `degraded: true` means Temporal was unreachable and
|
|
444
505
|
* `status` is the last-known value; `retry_after_seconds` carries the
|
|
445
|
-
* server's backoff hint when present.
|
|
446
|
-
*
|
|
506
|
+
* server's backoff hint when present. A failed run's stored report, `error`,
|
|
507
|
+
* is checked field by field (see `RunErrorReport`). Throws
|
|
508
|
+
* `RunLifecycleUnavailableError` when the lifecycle routes are absent (a bare
|
|
509
|
+
* runner).
|
|
447
510
|
*/
|
|
448
511
|
getRunStatus(runId: string, options?: {
|
|
449
512
|
signal?: AbortSignal;
|
|
@@ -477,8 +540,18 @@ export declare class PipelexApiClient implements MTHDSProtocol<DictPipeOutput> {
|
|
|
477
540
|
* Whether the configured server serves the durable run lifecycle, decided
|
|
478
541
|
* via the `GET /v1/version` handshake and cached for the client's lifetime. A
|
|
479
542
|
* bare `pipelex-api` runner has no run store; anything else is assumed hosted.
|
|
480
|
-
*
|
|
481
|
-
*
|
|
543
|
+
*
|
|
544
|
+
* The rule, the one the Python SDK follows: an answer that is not a usable
|
|
545
|
+
* version means assume hosted (the SDK default), and let the start surface the
|
|
546
|
+
* real error; no answer at all propagates, uncached. An answer is anything the
|
|
547
|
+
* server sent back: a non-2xx status, a body that is not JSON, not UTF-8 or no
|
|
548
|
+
* version, and a body that arrived but could not be decoded, such as a broken
|
|
549
|
+
* gzip stream, which `requestRaw` reports as an `ApiUnreachableError` carrying
|
|
550
|
+
* the decompressor's code (see `isUndecodableBody`).
|
|
551
|
+
*
|
|
552
|
+
* @throws {ApiUnreachableError} The handshake got no answer. Nothing is cached,
|
|
553
|
+
* so the next call asks again, and no start is sent to a host that did not
|
|
554
|
+
* answer: sending it would wait a second time for the same silence.
|
|
482
555
|
*/
|
|
483
556
|
private supportsRunLifecycle;
|
|
484
557
|
/**
|
|
@@ -488,8 +561,19 @@ export declare class PipelexApiClient implements MTHDSProtocol<DictPipeOutput> {
|
|
|
488
561
|
* path that survives the gateway's ~30s synchronous ceiling.
|
|
489
562
|
* - **Bare runner** (no run store): the blocking `POST /v1/execute`, which
|
|
490
563
|
* has no gateway cap off-platform and returns the native `pipe_output`.
|
|
564
|
+
*
|
|
565
|
+
* `pollOptions` are the wait's options, plus `onStarted`, called once with the
|
|
566
|
+
* start acknowledgement as soon as the durable run exists, so the caller holds
|
|
567
|
+
* the run's id while it waits; never on the blocking path, which has none to
|
|
568
|
+
* give; and `onStarting`, called right before each request that may create a
|
|
569
|
+
* run, so the caller knows until then that none exists (see
|
|
570
|
+
* `StartAndWaitForResultOptions`).
|
|
571
|
+
*
|
|
572
|
+
* `pollOptions.signal` is also read before the run is created: a caller that aborts while the
|
|
573
|
+
* version handshake is in flight gets its abort, and neither the start nor the blocking execute
|
|
574
|
+
* is sent. Once one of them is sent, the abort stops only the wait.
|
|
491
575
|
*/
|
|
492
|
-
startAndWaitForResult(options: PipelexStartOptions, pollOptions?:
|
|
576
|
+
startAndWaitForResult(options: PipelexStartOptions, pollOptions?: StartAndWaitForResultOptions): Promise<RunResults>;
|
|
493
577
|
/** The authenticated user's profile — `GET /v1/me`. */
|
|
494
578
|
getMe(): Promise<UserProfile>;
|
|
495
579
|
/**
|
|
@@ -668,7 +752,11 @@ export declare class PipelexApiClient implements MTHDSProtocol<DictPipeOutput> {
|
|
|
668
752
|
* paths it sits at, errors as values. See `docs/artifact-download.md`.
|
|
669
753
|
*/
|
|
670
754
|
downloadArtifacts(request: DownloadArtifactsRequest): Promise<DownloadArtifactsResult>;
|
|
671
|
-
/**
|
|
755
|
+
/**
|
|
756
|
+
* Upload a base64 file — `POST /v1/upload`. An answer with no non-empty string `uri` names no
|
|
757
|
+
* stored file, so it is an answer the SDK cannot read: an `ApiResponseError`, `runtime` and
|
|
758
|
+
* not retryable, which `uploadFile` wraps as an `UploadTransportError` with code `unexpected`.
|
|
759
|
+
*/
|
|
672
760
|
upload(input: UploadInput): Promise<UploadedFile>;
|
|
673
761
|
/**
|
|
674
762
|
* Request a grant to upload one file straight to storage — `POST /v1/upload/grant`.
|
|
@@ -771,7 +859,8 @@ export declare class PipelexApiClient implements MTHDSProtocol<DictPipeOutput> {
|
|
|
771
859
|
*
|
|
772
860
|
* The ONLY call that returns `mthds_contents` (what the run actually
|
|
773
861
|
* executed) and `inputs`. Kept off the status read, which pollers hit every
|
|
774
|
-
* few seconds.
|
|
862
|
+
* few seconds. A failed run's stored report, `error`, is checked field by
|
|
863
|
+
* field (see `RunErrorReport`).
|
|
775
864
|
*/
|
|
776
865
|
getRunDetail(runId: string): Promise<RunDetail>;
|
|
777
866
|
/** Patch a run's status (admin/manual) — `PUT /v1/runs/{id}`. */
|
|
@@ -789,3 +878,22 @@ export declare class PipelexApiClient implements MTHDSProtocol<DictPipeOutput> {
|
|
|
789
878
|
*/
|
|
790
879
|
private executeBlocking;
|
|
791
880
|
}
|
|
881
|
+
/**
|
|
882
|
+
* Whether a request that failed `elapsedMs` after it was sent was cut off by the hosted gateway's
|
|
883
|
+
* ~30-second limit on a request it waits on, rather than refused.
|
|
884
|
+
*
|
|
885
|
+
* It is when, after at least ~28 seconds, the failure is a `503` or `504` answer, or the client's
|
|
886
|
+
* own time limit (`ApiUnreachableError` with the code `ABORT_TIMEOUT`). A fast `503` is the API
|
|
887
|
+
* saying the request was not handled, and any other unreachable host is never the gateway's
|
|
888
|
+
* cut-off, however long it took. The fetch API cannot say whether `ABORT_TIMEOUT` ran out before
|
|
889
|
+
* the connection was made, so it is read as the gateway's; with Node's own dispatcher it never
|
|
890
|
+
* does past the threshold, since undici gives up a connection that does not come after ten
|
|
891
|
+
* seconds (`UND_ERR_CONNECT_TIMEOUT`), the TLS handshake included. The Python SDK's
|
|
892
|
+
* `is_gateway_cut_off` reads the same failures, its `ABORT_TIMEOUT` being httpx's read or write
|
|
893
|
+
* timeout.
|
|
894
|
+
*
|
|
895
|
+
* The blocking `execute` turns such a failure into a `PipelineExecuteTimeoutError`. A caller timing
|
|
896
|
+
* a request that may create a run, such as `start` from `startAndWaitForResult`'s `onStarting`,
|
|
897
|
+
* reads it to know the server may still be handling the request the gateway gave up on.
|
|
898
|
+
*/
|
|
899
|
+
export declare function isGatewayCutOff(error: unknown, elapsedMs: number): boolean;
|