@pipelex/sdk 0.39.0 → 0.41.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 +3 -0
- package/dist/bundle-resources.d.ts +62 -0
- package/dist/bundle-resources.js +165 -0
- package/dist/bundle-resources.js.map +1 -0
- package/dist/cli/script.d.ts +1 -1
- package/dist/cli/source.d.ts +2 -1
- package/dist/cli/source.js +61 -3
- package/dist/cli/source.js.map +1 -1
- package/dist/client.d.ts +107 -23
- package/dist/client.js +216 -113
- package/dist/client.js.map +1 -1
- package/dist/errors.d.ts +16 -5
- package/dist/errors.js +15 -5
- package/dist/errors.js.map +1 -1
- package/dist/hooks/bundle-gather.d.ts +28 -1
- package/dist/hooks/bundle-gather.js +163 -3
- package/dist/hooks/bundle-gather.js.map +1 -1
- package/dist/hooks/claude-mthds-check.d.ts +4 -2
- package/dist/hooks/claude-mthds-check.js +5 -2
- package/dist/hooks/claude-mthds-check.js.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/models.d.ts +42 -4
- package/dist/prepare-inputs.d.ts +48 -7
- package/dist/prepare-inputs.js +236 -35
- package/dist/prepare-inputs.js.map +1 -1
- package/dist/product-models.d.ts +46 -0
- package/dist/runs.d.ts +11 -0
- package/dist/runs.js +35 -0
- package/dist/runs.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/docs/architecture.md +5 -3
- package/docs/bundle-resources.md +107 -0
- package/docs/cli.md +1 -0
- package/docs/crate-routes.md +5 -1
- package/docs/errors.md +4 -3
- package/docs/hook-bundle.md +2 -0
- package/docs/input-preparation.md +9 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -102,6 +102,8 @@ const client = new PipelexApiClient({ apiKey: process.env.PIPELEX_API_KEY });
|
|
|
102
102
|
|
|
103
103
|
const me = await client.getMe(); // GET /v1/me
|
|
104
104
|
const page = await client.listMethods(); // GET /v1/methods — one page: { items, nextCursor }
|
|
105
|
+
// Only the methods never published. A filtered page can be empty and still carry a nextCursor.
|
|
106
|
+
const drafts = await client.listMethods({ published: false });
|
|
105
107
|
for await (const method of client.iterateMethods()) {
|
|
106
108
|
// follows the cursor for callers that genuinely want the whole catalog
|
|
107
109
|
}
|
|
@@ -209,6 +211,7 @@ These pages ship inside the published package, so a reader who has only installe
|
|
|
209
211
|
| [`docs/run-usage.md`](./docs/run-usage.md) | What a run consumed, record by record, and `summarizeUsage` which folds them into one reading |
|
|
210
212
|
| [`docs/artifact-download.md`](./docs/artifact-download.md) | Turning the `pipelex-storage://` references a run produced back into bytes: `locateArtifacts`, `collectArtifacts`, `resolveArtifacts`, `fetchArtifact`, `downloadArtifacts`, and how a saved file is named after the field it fills |
|
|
211
213
|
| [`docs/input-preparation.md`](./docs/input-preparation.md) | The other direction — `uploadFile` and `prepareInputs`, which turn local files into references a run can take, and the upload grant a browser page sends a file with |
|
|
214
|
+
| [`docs/bundle-resources.md`](./docs/bundle-resources.md) | Sending the files a bundle's steps read, such as a `PipeDocGen` step's template, as `resources` beside its `.mthds` contents: where they go, what is refused and by whom, and the template check's warnings |
|
|
212
215
|
| [`docs/crate-routes.md`](./docs/crate-routes.md) | `resolve`, `codegen` and `pipeIo` — the normalized crate, the stamped types, and a method's I/O artifacts without a validation — and the offline `runCodegenCheck` that guards a committed tree |
|
|
213
216
|
| [`docs/client-identification.md`](./docs/client-identification.md) | The `User-Agent` every API request carries, and `appInfo`, the option that puts your program's name in front of it |
|
|
214
217
|
| [`docs/errors.md`](./docs/errors.md) | The verdict every error carries (`retryable`, `errorDomain`, `errorVerdictOf`), a failed run's stored error report on `RunFailedError` and `RunRead`, and every member of a refused request's `ApiResponseError`, with the fields to branch on |
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The files a bundle's steps read, sent with the bundle as the request's `resources`.
|
|
3
|
+
*
|
|
4
|
+
* A bundle sent as content has no directory, so a file one of its steps reads from beside the
|
|
5
|
+
* bundle, such as a `PipeDocGen` step's `template_file`, has to travel with it. The runner takes
|
|
6
|
+
* such files as `resources`: a JSON object mapping each file's path, exactly as the step names it,
|
|
7
|
+
* relative to the bundle and written with forward slashes, to the file's bytes in standard padded
|
|
8
|
+
* base64. It takes them beside `mthds_contents` (or a method bundle) on `/v1/validate`,
|
|
9
|
+
* `/v1/execute` and `/v1/start`, and beside inline `files[]` on `/v1/pipe-io`, `/v1/resolve` and
|
|
10
|
+
* `/v1/codegen`. A caller hands this SDK the bytes, keyed by that path, and the SDK encodes them.
|
|
11
|
+
*
|
|
12
|
+
* The SDK refuses before any request what the runner refuses for certain about the keys, with the
|
|
13
|
+
* runner's own rule (`resource_path_refusal` in pipelex's `bundle_resource.py`): an empty path, a
|
|
14
|
+
* backslash, a colon, a NUL character, an absolute path, a `..` segment, a path naming no file,
|
|
15
|
+
* and two keys naming one file once `.` segments and repeated slashes collapse. Each is a
|
|
16
|
+
* `RequestArgumentError` naming the key, where the runner answers a `422` `InvalidResourcePath`.
|
|
17
|
+
* The sizes are left to the server, since a deployment configures them: 32 files, 5 MiB each and
|
|
18
|
+
* 10 MiB in all by default, a `413` `PayloadTooLarge` beyond, and 512 KiB in all for the `.html`
|
|
19
|
+
* template files, a `413` `BundleResourcesTooLargeError`. So is every rule that needs the parsed
|
|
20
|
+
* bundle: a file no step names is a `422` `BundleResourceNotNamedError`.
|
|
21
|
+
*/
|
|
22
|
+
/** The bytes of one file a bundle's steps read: the byte forms `uploadFile` takes. */
|
|
23
|
+
export type BundleResourceBytes = Uint8Array | ArrayBuffer | Blob;
|
|
24
|
+
/**
|
|
25
|
+
* The files a bundle's steps read, such as a `PipeDocGen` step's template file, keyed by the path
|
|
26
|
+
* the step names (`templates/invoice.docx`), each as its bytes. `./templates/invoice.docx` names
|
|
27
|
+
* the same file, so only one of the two spellings may be given.
|
|
28
|
+
*/
|
|
29
|
+
export type BundleResources = Readonly<Record<string, BundleResourceBytes>>;
|
|
30
|
+
/**
|
|
31
|
+
* Whether `resources` is a plain object, the one shape a map of paths to bytes takes: its
|
|
32
|
+
* prototype is `Object.prototype` or `null`. A `Map`, an array or a class instance is not one,
|
|
33
|
+
* and the encoder refuses it rather than reading it as a map with no file in it.
|
|
34
|
+
*/
|
|
35
|
+
export declare function isResourceMap(resources: unknown): resources is Record<string, unknown>;
|
|
36
|
+
/**
|
|
37
|
+
* Whether `resources` carries at least one file. An absent, `null` or empty map carries none, so
|
|
38
|
+
* it is not sent, as an empty bundle encoding is not. A value that is not a plain object carries
|
|
39
|
+
* none either; the encoder refuses it.
|
|
40
|
+
*/
|
|
41
|
+
export declare function hasBundleResources(resources: unknown): boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Why `path` cannot name a file inside a bundle, or `undefined` when it can — the runner's rule,
|
|
44
|
+
* held by the key of a file sent with a bundle and by the path a step names.
|
|
45
|
+
*/
|
|
46
|
+
export declare function bundleResourcePathRefusal(path: string): string | undefined;
|
|
47
|
+
/**
|
|
48
|
+
* The one spelling of a bundle-relative path the runner keys a file by: `.` segments and repeated
|
|
49
|
+
* slashes collapse, so `./templates//invoice.docx` is `templates/invoice.docx`. Only meaningful
|
|
50
|
+
* for a path {@link bundleResourcePathRefusal} accepts.
|
|
51
|
+
*/
|
|
52
|
+
export declare function canonicalBundleResourcePath(path: string): string;
|
|
53
|
+
/**
|
|
54
|
+
* Encode `resources` for the wire: each key as given, each value as its bytes in standard padded
|
|
55
|
+
* base64. Returns `undefined` when there is nothing to send, so the key stays off the wire.
|
|
56
|
+
*
|
|
57
|
+
* Every key is checked before any value is read, so a refused path costs no read of a `Blob`.
|
|
58
|
+
*
|
|
59
|
+
* @throws {RequestArgumentError} `resources` is not a map of paths to bytes, a key cannot name a
|
|
60
|
+
* file inside the bundle, two keys name one file, or a value is not bytes.
|
|
61
|
+
*/
|
|
62
|
+
export declare function encodeBundleResources(resources: BundleResources | null | undefined): Promise<Record<string, string> | undefined>;
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The files a bundle's steps read, sent with the bundle as the request's `resources`.
|
|
3
|
+
*
|
|
4
|
+
* A bundle sent as content has no directory, so a file one of its steps reads from beside the
|
|
5
|
+
* bundle, such as a `PipeDocGen` step's `template_file`, has to travel with it. The runner takes
|
|
6
|
+
* such files as `resources`: a JSON object mapping each file's path, exactly as the step names it,
|
|
7
|
+
* relative to the bundle and written with forward slashes, to the file's bytes in standard padded
|
|
8
|
+
* base64. It takes them beside `mthds_contents` (or a method bundle) on `/v1/validate`,
|
|
9
|
+
* `/v1/execute` and `/v1/start`, and beside inline `files[]` on `/v1/pipe-io`, `/v1/resolve` and
|
|
10
|
+
* `/v1/codegen`. A caller hands this SDK the bytes, keyed by that path, and the SDK encodes them.
|
|
11
|
+
*
|
|
12
|
+
* The SDK refuses before any request what the runner refuses for certain about the keys, with the
|
|
13
|
+
* runner's own rule (`resource_path_refusal` in pipelex's `bundle_resource.py`): an empty path, a
|
|
14
|
+
* backslash, a colon, a NUL character, an absolute path, a `..` segment, a path naming no file,
|
|
15
|
+
* and two keys naming one file once `.` segments and repeated slashes collapse. Each is a
|
|
16
|
+
* `RequestArgumentError` naming the key, where the runner answers a `422` `InvalidResourcePath`.
|
|
17
|
+
* The sizes are left to the server, since a deployment configures them: 32 files, 5 MiB each and
|
|
18
|
+
* 10 MiB in all by default, a `413` `PayloadTooLarge` beyond, and 512 KiB in all for the `.html`
|
|
19
|
+
* template files, a `413` `BundleResourcesTooLargeError`. So is every rule that needs the parsed
|
|
20
|
+
* bundle: a file no step names is a `422` `BundleResourceNotNamedError`.
|
|
21
|
+
*/
|
|
22
|
+
import { RequestArgumentError } from "./errors.js";
|
|
23
|
+
import { bytesToBase64 } from "./upload.js";
|
|
24
|
+
/**
|
|
25
|
+
* Whether `resources` is a plain object, the one shape a map of paths to bytes takes: its
|
|
26
|
+
* prototype is `Object.prototype` or `null`. A `Map`, an array or a class instance is not one,
|
|
27
|
+
* and the encoder refuses it rather than reading it as a map with no file in it.
|
|
28
|
+
*/
|
|
29
|
+
export function isResourceMap(resources) {
|
|
30
|
+
if (typeof resources !== "object" || resources === null)
|
|
31
|
+
return false;
|
|
32
|
+
const prototype = Object.getPrototypeOf(resources);
|
|
33
|
+
return prototype === Object.prototype || prototype === null;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Whether `resources` carries at least one file. An absent, `null` or empty map carries none, so
|
|
37
|
+
* it is not sent, as an empty bundle encoding is not. A value that is not a plain object carries
|
|
38
|
+
* none either; the encoder refuses it.
|
|
39
|
+
*/
|
|
40
|
+
export function hasBundleResources(resources) {
|
|
41
|
+
return isResourceMap(resources) && Object.keys(resources).length > 0;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Python's whitespace, the set `str.strip()` removes and `str.isspace()` accepts, which the
|
|
45
|
+
* runner's rule tests a path against. It differs from JavaScript's `trim()`: it holds the
|
|
46
|
+
* separators U+001C to U+001F and U+0085, and not the byte-order mark U+FEFF.
|
|
47
|
+
*/
|
|
48
|
+
const PYTHON_WHITESPACE = new Set([
|
|
49
|
+
0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x85, 0xa0, 0x1680, 0x2000, 0x2001,
|
|
50
|
+
0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, 0x2009, 0x200a, 0x2028, 0x2029, 0x202f,
|
|
51
|
+
0x205f, 0x3000,
|
|
52
|
+
]);
|
|
53
|
+
/** Whether `path` holds nothing but Python's whitespace: `not path.strip()`, the runner's test. */
|
|
54
|
+
function isBlankForPython(path) {
|
|
55
|
+
for (const character of path) {
|
|
56
|
+
if (!PYTHON_WHITESPACE.has(character.codePointAt(0)))
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Why `path` cannot name a file inside a bundle, or `undefined` when it can — the runner's rule,
|
|
63
|
+
* held by the key of a file sent with a bundle and by the path a step names.
|
|
64
|
+
*/
|
|
65
|
+
export function bundleResourcePathRefusal(path) {
|
|
66
|
+
if (isBlankForPython(path))
|
|
67
|
+
return "it is empty";
|
|
68
|
+
if (path.includes("\\"))
|
|
69
|
+
return "it holds a backslash; write the path with forward slashes";
|
|
70
|
+
if (path.includes(":"))
|
|
71
|
+
return "it holds a colon";
|
|
72
|
+
if (path.includes("\0"))
|
|
73
|
+
return "it holds a NUL character";
|
|
74
|
+
if (path.startsWith("/"))
|
|
75
|
+
return "it is absolute; write it relative to the bundle";
|
|
76
|
+
const segments = pathSegments(path);
|
|
77
|
+
if (segments.includes(".."))
|
|
78
|
+
return "it leaves the bundle through a '..' segment";
|
|
79
|
+
if (segments.length === 0)
|
|
80
|
+
return "it names no file";
|
|
81
|
+
return undefined;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* The one spelling of a bundle-relative path the runner keys a file by: `.` segments and repeated
|
|
85
|
+
* slashes collapse, so `./templates//invoice.docx` is `templates/invoice.docx`. Only meaningful
|
|
86
|
+
* for a path {@link bundleResourcePathRefusal} accepts.
|
|
87
|
+
*/
|
|
88
|
+
export function canonicalBundleResourcePath(path) {
|
|
89
|
+
return pathSegments(path).join("/");
|
|
90
|
+
}
|
|
91
|
+
function pathSegments(path) {
|
|
92
|
+
return path.split("/").filter((segment) => segment !== "" && segment !== ".");
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Encode `resources` for the wire: each key as given, each value as its bytes in standard padded
|
|
96
|
+
* base64. Returns `undefined` when there is nothing to send, so the key stays off the wire.
|
|
97
|
+
*
|
|
98
|
+
* Every key is checked before any value is read, so a refused path costs no read of a `Blob`.
|
|
99
|
+
*
|
|
100
|
+
* @throws {RequestArgumentError} `resources` is not a map of paths to bytes, a key cannot name a
|
|
101
|
+
* file inside the bundle, two keys name one file, or a value is not bytes.
|
|
102
|
+
*/
|
|
103
|
+
export async function encodeBundleResources(resources) {
|
|
104
|
+
if (resources === undefined || resources === null)
|
|
105
|
+
return undefined;
|
|
106
|
+
if (!isResourceMap(resources)) {
|
|
107
|
+
throw new RequestArgumentError("resources must be a plain object mapping each file's path, as the step names it, to the " +
|
|
108
|
+
`file's bytes; got ${describeValue(resources)}.`);
|
|
109
|
+
}
|
|
110
|
+
// Read once: a second read of a proxy or a getter could differ from the one checked.
|
|
111
|
+
const entries = Object.entries(resources);
|
|
112
|
+
if (entries.length === 0)
|
|
113
|
+
return undefined;
|
|
114
|
+
const pathByCanonical = new Map();
|
|
115
|
+
for (const [path] of entries) {
|
|
116
|
+
const refusal = bundleResourcePathRefusal(path);
|
|
117
|
+
if (refusal !== undefined) {
|
|
118
|
+
throw new RequestArgumentError(`resources key ${JSON.stringify(path)} cannot name a file inside the bundle: ${refusal}.`);
|
|
119
|
+
}
|
|
120
|
+
const canonical = canonicalBundleResourcePath(path);
|
|
121
|
+
const first = pathByCanonical.get(canonical);
|
|
122
|
+
if (first !== undefined) {
|
|
123
|
+
throw new RequestArgumentError(`resources keys ${JSON.stringify(first)} and ${JSON.stringify(path)} name the same file ` +
|
|
124
|
+
`"${canonical}": send it once.`);
|
|
125
|
+
}
|
|
126
|
+
pathByCanonical.set(canonical, path);
|
|
127
|
+
}
|
|
128
|
+
// A null prototype, so a key such as `__proto__` is an own property that reaches the wire.
|
|
129
|
+
const wire = Object.create(null);
|
|
130
|
+
for (const [path, value] of entries) {
|
|
131
|
+
wire[path] = bytesToBase64(await resourceBytes(path, value));
|
|
132
|
+
}
|
|
133
|
+
return wire;
|
|
134
|
+
}
|
|
135
|
+
async function resourceBytes(path, value) {
|
|
136
|
+
if (value instanceof Uint8Array)
|
|
137
|
+
return value;
|
|
138
|
+
if (value instanceof ArrayBuffer)
|
|
139
|
+
return new Uint8Array(value);
|
|
140
|
+
if (typeof Blob !== "undefined" && value instanceof Blob) {
|
|
141
|
+
return new Uint8Array(await value.arrayBuffer());
|
|
142
|
+
}
|
|
143
|
+
throw new RequestArgumentError(`resources[${JSON.stringify(path)}] must be the file's bytes (a Uint8Array, an ArrayBuffer ` +
|
|
144
|
+
`or a Blob); got ${describeValue(value)}.` +
|
|
145
|
+
(typeof value === "string"
|
|
146
|
+
? " A string is read neither as a path nor as base64: read the file and pass its bytes."
|
|
147
|
+
: ""));
|
|
148
|
+
}
|
|
149
|
+
function describeValue(value) {
|
|
150
|
+
if (value === null)
|
|
151
|
+
return "null";
|
|
152
|
+
if (Array.isArray(value))
|
|
153
|
+
return "an array";
|
|
154
|
+
if (value instanceof Map)
|
|
155
|
+
return "a Map; pass Object.fromEntries(map)";
|
|
156
|
+
if (typeof value === "string")
|
|
157
|
+
return "a string";
|
|
158
|
+
if (typeof value === "object") {
|
|
159
|
+
const name = Object.getPrototypeOf(value)
|
|
160
|
+
?.constructor?.name;
|
|
161
|
+
return typeof name === "string" && name !== "" ? `an instance of ${name}` : "an object";
|
|
162
|
+
}
|
|
163
|
+
return `a value of type ${typeof value}`;
|
|
164
|
+
}
|
|
165
|
+
//# sourceMappingURL=bundle-resources.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bundle-resources.js","sourceRoot":"","sources":["../src/bundle-resources.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/script.d.ts
CHANGED
|
@@ -15,7 +15,7 @@ import type { CommandIO } from "./io.js";
|
|
|
15
15
|
* update notice and npm 12's run notices off the script's stderr, which carries the command's
|
|
16
16
|
* own lines, while npm's warnings and errors still print.
|
|
17
17
|
*/
|
|
18
|
-
export declare const SCRIPT_RUNNER = "npx --yes --no-update-notifier --loglevel=warn @pipelex/sdk@0.
|
|
18
|
+
export declare const SCRIPT_RUNNER = "npx --yes --no-update-notifier --loglevel=warn @pipelex/sdk@0.41.0";
|
|
19
19
|
export declare const SCRIPT_WRITER = "@pipelex/sdk";
|
|
20
20
|
export declare const SCRIPT_NEEDS = "Node 22.12 or later";
|
|
21
21
|
/** Run `pipelex-sdk script` and return its exit code. */
|
package/dist/cli/source.d.ts
CHANGED
|
@@ -43,7 +43,8 @@ export interface DescribedPipe {
|
|
|
43
43
|
* the same selection the run's input preparation makes.
|
|
44
44
|
*
|
|
45
45
|
* @throws {CommandError} When the method does not load, or the answer does not describe the pipe
|
|
46
|
-
* it selected
|
|
46
|
+
* it selected or describes it with an input form the walk or the template cannot read. A refusal
|
|
47
|
+
* of the request itself propagates as the SDK's `ApiResponseError`.
|
|
47
48
|
* @throws {Interrupted} When the person interrupts the wait.
|
|
48
49
|
*/
|
|
49
50
|
export declare function describePipe(client: PipelexApiClient, source: MethodSource, pipe: string | undefined, interrupt: AbortSignal): Promise<DescribedPipe>;
|
package/dist/cli/source.js
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* bundle, and to the run as `mthds_contents`, in the same order. An address travels as
|
|
6
6
|
* `method_ref` and a catalog id as `method_id`, both resolved by the server.
|
|
7
7
|
*/
|
|
8
|
+
import { inputFormFault } from "../index.js";
|
|
8
9
|
import { CommandError, EXIT_FAILED, untilInterrupted } from "./io.js";
|
|
9
10
|
import { loadFailureLines, METHOD_DOES_NOT_LOAD_SENTENCE } from "./present.js";
|
|
10
11
|
export function crateSelector(source) {
|
|
@@ -33,7 +34,8 @@ export function runSelector(source) {
|
|
|
33
34
|
* the same selection the run's input preparation makes.
|
|
34
35
|
*
|
|
35
36
|
* @throws {CommandError} When the method does not load, or the answer does not describe the pipe
|
|
36
|
-
* it selected
|
|
37
|
+
* it selected or describes it with an input form the walk or the template cannot read. A refusal
|
|
38
|
+
* of the request itself propagates as the SDK's `ApiResponseError`.
|
|
37
39
|
* @throws {Interrupted} When the person interrupts the wait.
|
|
38
40
|
*/
|
|
39
41
|
export async function describePipe(client, source, pipe, interrupt) {
|
|
@@ -58,12 +60,68 @@ export async function describePipe(client, source, pipe, interrupt) {
|
|
|
58
60
|
const inputForm = report.input_form;
|
|
59
61
|
if (typeof pipeRef !== "string" ||
|
|
60
62
|
!isPlainObject(inputForm) ||
|
|
61
|
-
!
|
|
63
|
+
!Object.hasOwn(inputForm, pipeRef)) {
|
|
62
64
|
throw new CommandError("the API's pipe I/O answer does not describe the pipe it selected.", {
|
|
63
65
|
exitCode: EXIT_FAILED,
|
|
64
66
|
});
|
|
65
67
|
}
|
|
66
|
-
|
|
68
|
+
// The template is rendered from this entry, so it is checked as input preparation checks it,
|
|
69
|
+
// and then for what the template reads beyond the walk: a malformed entry would otherwise crash
|
|
70
|
+
// the rendering or print a template under made-up keys. The sentence is the Python command's,
|
|
71
|
+
// printed when its client cannot parse an entry, which cannot say where, so neither command
|
|
72
|
+
// names the fault. Python's closed models refuse more than this, such as a member the standard
|
|
73
|
+
// does not define, which the template never reads.
|
|
74
|
+
const entry = inputForm[pipeRef];
|
|
75
|
+
if (inputFormFault(entry) !== undefined || !templateReadable(entry)) {
|
|
76
|
+
throw new CommandError("the API's pipe I/O answer describes the pipe it selected with a malformed input form.", { exitCode: EXIT_FAILED });
|
|
77
|
+
}
|
|
78
|
+
return { report, pipeRef, descriptor: entry };
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Whether an entry `inputFormFault` passed also holds what the inputs template reads beyond the
|
|
82
|
+
* walk, in a shape it can render: every node's `concept_ref` a string, its `refines` a list of
|
|
83
|
+
* strings, an enum's `choices` a list and a list's `item_count` a whole number of at least two,
|
|
84
|
+
* the last three when present. Members the template only tests for truth are not checked.
|
|
85
|
+
*/
|
|
86
|
+
function templateReadable(entry) {
|
|
87
|
+
return entry.fields.every(templateReadableNode);
|
|
88
|
+
}
|
|
89
|
+
function templateReadableNode(node) {
|
|
90
|
+
if (node.concept_ref !== undefined && typeof node.concept_ref !== "string")
|
|
91
|
+
return false;
|
|
92
|
+
if (node.refines !== undefined &&
|
|
93
|
+
node.refines !== null &&
|
|
94
|
+
!(Array.isArray(node.refines) && node.refines.every((ref) => typeof ref === "string"))) {
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
// Every kind is listed, so a kind a newer `mthds` pin adds stops the build here until the
|
|
98
|
+
// template's reads of it are checked, as it does in the walk's own table.
|
|
99
|
+
const kind = node.kind;
|
|
100
|
+
switch (kind) {
|
|
101
|
+
case "text":
|
|
102
|
+
case "prose":
|
|
103
|
+
case "date":
|
|
104
|
+
case "number":
|
|
105
|
+
case "boolean":
|
|
106
|
+
case "document":
|
|
107
|
+
case "image":
|
|
108
|
+
case "unknown":
|
|
109
|
+
return true;
|
|
110
|
+
case "object":
|
|
111
|
+
return templateReadable(node);
|
|
112
|
+
case "enum":
|
|
113
|
+
return Array.isArray(node.choices);
|
|
114
|
+
case "list":
|
|
115
|
+
return ((node.item_count === undefined ||
|
|
116
|
+
node.item_count === null ||
|
|
117
|
+
(Number.isInteger(node.item_count) && node.item_count >= 2)) &&
|
|
118
|
+
templateReadableNode(node.item));
|
|
119
|
+
default: {
|
|
120
|
+
// Unreachable: `inputFormFault` refused a kind outside the walk's table.
|
|
121
|
+
const unreachable = kind;
|
|
122
|
+
return unreachable;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
67
125
|
}
|
|
68
126
|
function isPlainObject(value) {
|
|
69
127
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
package/dist/cli/source.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"source.js","sourceRoot":"","sources":["../../src/cli/source.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAUH,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AACtE,OAAO,EAAE,gBAAgB,EAAE,6BAA6B,EAAE,MAAM,cAAc,CAAC;AAc/E,MAAM,UAAU,aAAa,CAAC,MAAoB;IAChD,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;QACpB,KAAK,QAAQ;YACX,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;QAC/F,KAAK,SAAS;YACZ,OAAO,EAAE,UAAU,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC;QAC1C,KAAK,SAAS;YACZ,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC;IAC1C,CAAC;AACH,CAAC;AAED,4CAA4C;AAC5C,MAAM,UAAU,WAAW,CAAC,MAAoB;IAC9C,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;QACpB,KAAK,QAAQ;YACX,OAAO,EAAE,cAAc,EAAE,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACtE,KAAK,SAAS;YACZ,OAAO,EAAE,UAAU,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC;QAC1C,KAAK,SAAS;YACZ,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC;IAC1C,CAAC;AACH,CAAC;AASD
|
|
1
|
+
{"version":3,"file":"source.js","sourceRoot":"","sources":["../../src/cli/source.ts"],"names":[],"mappings":"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"}
|
package/dist/client.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { type GetRunResultOptions, type RunRead, type RunResults, type RunResult
|
|
|
4
4
|
import type { BillingPortalResponse, ChangePlanResponse, CheckoutResponse, InvoiceView, Membership, MembershipsResponse, ListMethodsQuery, ListMethodVersionsQuery, MethodData, MethodDeletionAccepted, MethodDraftInput, MethodPage, MethodPublishInput, MethodPublishResult, MethodRenameInput, MethodSummary, MethodVersion, MethodVersionPage, 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";
|
|
7
|
+
import type { BundleResources } from "./bundle-resources.js";
|
|
7
8
|
import type { PrepareInputsRequest, PreparedInputs } from "./prepare-inputs.js";
|
|
8
9
|
import type { BulkResolveStorageUrlsInput, BulkResolvedStorageUrls, DownloadArtifactsRequest, DownloadArtifactsResult, FetchArtifactOptions, ResolvedArtifact } from "./artifacts.js";
|
|
9
10
|
import { PipelexExecuteResult } from "./execute-result.js";
|
|
@@ -14,10 +15,11 @@ export interface MthdsFile {
|
|
|
14
15
|
uri?: string;
|
|
15
16
|
}
|
|
16
17
|
/**
|
|
17
|
-
* The Pipelex API's own run
|
|
18
|
-
*
|
|
19
|
-
* the
|
|
20
|
-
* or hosted (on `api.pipelex.com`, once the platform deploy
|
|
18
|
+
* The Pipelex API's own run arguments — the layer-2 arguments the RUNNER itself
|
|
19
|
+
* reads, beside the protocol's inline sources (`mthds_contents` and the bundle
|
|
20
|
+
* encodings): the `method_ref` run source, served by any pipelex-api >= 0.21.0
|
|
21
|
+
* deployment, bare or hosted (on `api.pipelex.com`, once the platform deploy
|
|
22
|
+
* carrying it lands), and the `resources` the bundle's steps read.
|
|
21
23
|
*
|
|
22
24
|
* Named options rather than `extra` entries, for the same reason as the hosted
|
|
23
25
|
* extensions below: `extra` remains the escape hatch for an extension this
|
|
@@ -43,6 +45,20 @@ export interface PipelexApiRunExtensions {
|
|
|
43
45
|
* An empty string is treated as absent and is not sent.
|
|
44
46
|
*/
|
|
45
47
|
method_ref?: string | null;
|
|
48
|
+
/**
|
|
49
|
+
* The files the bundle's steps read, such as a `PipeDocGen` step's `template_file`, keyed
|
|
50
|
+
* by the path the step names (`templates/invoice.docx`), each as its bytes (a `Uint8Array`,
|
|
51
|
+
* a Node `Buffer` included, an `ArrayBuffer` or a `Blob`). The client sends them as the
|
|
52
|
+
* wire's `resources`, each file in standard base64; see `docs/bundle-resources.md`.
|
|
53
|
+
*
|
|
54
|
+
* They accompany the bundle whose steps read them: inline `mthds_contents` or a method
|
|
55
|
+
* bundle (`files` / `bundle_b64`), or a hosted `method_id` the platform resolves. Beside a
|
|
56
|
+
* `method_ref` (whose files are its package's own), or with no source at all, they are
|
|
57
|
+
* rejected client-side, mirroring the server's `422`. A key that cannot name a file inside
|
|
58
|
+
* the bundle (absolute, a `..` segment, a backslash, a colon) is rejected client-side too.
|
|
59
|
+
* An absent, `null` or empty map is not sent.
|
|
60
|
+
*/
|
|
61
|
+
resources?: BundleResources | null;
|
|
46
62
|
}
|
|
47
63
|
/**
|
|
48
64
|
* The hosted API's own run arguments — the layer-3 extensions this client adds
|
|
@@ -104,6 +120,32 @@ export interface ValidateFilesOptions {
|
|
|
104
120
|
render?: string[];
|
|
105
121
|
/** Optional structured-view opt-in tokens, e.g. ["input_form", "output_form"]; sent only when given. */
|
|
106
122
|
views?: string[];
|
|
123
|
+
/**
|
|
124
|
+
* The files the bundle's steps read, such as a `PipeDocGen` step's `template_file`, keyed by
|
|
125
|
+
* the path the step names, each as its bytes; sent as `resources` (see {@link ValidateOptions}).
|
|
126
|
+
*/
|
|
127
|
+
resources?: BundleResources | null;
|
|
128
|
+
/**
|
|
129
|
+
* Per-call request ceiling; defaults to the 20-min execute ceiling. A positive number
|
|
130
|
+
* no larger than 2147483647, the longest delay a timer honours, else a `RangeError`.
|
|
131
|
+
*/
|
|
132
|
+
timeoutMs?: number;
|
|
133
|
+
/** Caller-driven cancellation; the abort reason propagates untouched. */
|
|
134
|
+
signal?: AbortSignal;
|
|
135
|
+
}
|
|
136
|
+
/** `validate()`'s last argument: what rides beside the method, and the call's own transport. */
|
|
137
|
+
export interface ValidateOptions {
|
|
138
|
+
/**
|
|
139
|
+
* The files the bundle's steps read, such as a `PipeDocGen` step's `template_file`, keyed by
|
|
140
|
+
* the path the step names (`templates/invoice.docx`), each as its bytes (a `Uint8Array`, a
|
|
141
|
+
* Node `Buffer` included, an `ArrayBuffer` or a `Blob`). Sent as the wire's `resources`, each
|
|
142
|
+
* file in standard base64; see `docs/bundle-resources.md`. They accompany inline contents, or
|
|
143
|
+
* a hosted `{ method_id }` the platform resolves; beside a `{ method_ref }` they are rejected
|
|
144
|
+
* client-side, mirroring the server's `422`. A step whose template file was not sent makes the
|
|
145
|
+
* verdict invalid, saying so; the dry run checks an office template file it was sent and adds
|
|
146
|
+
* its findings to the valid arm's `warnings` (`template_check_warning`).
|
|
147
|
+
*/
|
|
148
|
+
resources?: BundleResources | null;
|
|
107
149
|
/**
|
|
108
150
|
* Per-call request ceiling; defaults to the 20-min execute ceiling. A positive number
|
|
109
151
|
* no larger than 2147483647, the longest delay a timer honours, else a `RangeError`.
|
|
@@ -356,6 +398,15 @@ export declare class PipelexApiClient implements MTHDSProtocol<DictPipeOutput> {
|
|
|
356
398
|
* the field regardless — which is why `PipelexValidationReport.input_form` is typed
|
|
357
399
|
* optional rather than required.
|
|
358
400
|
*
|
|
401
|
+
* `options.resources` sends the files the bundle's steps read, such as a
|
|
402
|
+
* `PipeDocGen` step's `template_file`, keyed by the path the step names, each as
|
|
403
|
+
* its bytes (see {@link ValidateOptions}). A step whose template file was not sent
|
|
404
|
+
* is an `is_valid: false` verdict saying so, and a template check's findings in an
|
|
405
|
+
* office template file ride the valid arm's `warnings`. A key no step names, or
|
|
406
|
+
* files over the server's limits, are no-verdict refusals: a `422`
|
|
407
|
+
* `BundleResourceNotNamedError`, a `413` `PayloadTooLarge` or
|
|
408
|
+
* `BundleResourcesTooLargeError`.
|
|
409
|
+
*
|
|
359
410
|
* A `{ method_ref }` source makes the server clone a repository before it
|
|
360
411
|
* validates anything, and it needs no special budget here: this route already
|
|
361
412
|
* defaults to the 20-minute execute ceiling, which clears the internal
|
|
@@ -364,10 +415,7 @@ export declare class PipelexApiClient implements MTHDSProtocol<DictPipeOutput> {
|
|
|
364
415
|
* exists to RAISE routes whose default is the ~30s poll ceiling; applying it here
|
|
365
416
|
* would lower this one.
|
|
366
417
|
*/
|
|
367
|
-
validate(source: string[] | ValidateMethodSelector, allowSignatures?: boolean, mthdsSources?: string[], render?: string[], views?: string[], options?:
|
|
368
|
-
timeoutMs?: number;
|
|
369
|
-
signal?: AbortSignal;
|
|
370
|
-
}): Promise<PipelexValidationResult>;
|
|
418
|
+
validate(source: string[] | ValidateMethodSelector, allowSignatures?: boolean, mthdsSources?: string[], render?: string[], views?: string[], options?: ValidateOptions): Promise<PipelexValidationResult>;
|
|
371
419
|
/**
|
|
372
420
|
* Validate paired MTHDS files while preserving URI attribution for diagnostics.
|
|
373
421
|
*
|
|
@@ -418,10 +466,11 @@ export declare class PipelexApiClient implements MTHDSProtocol<DictPipeOutput> {
|
|
|
418
466
|
* never on a message.
|
|
419
467
|
*
|
|
420
468
|
* All of these are static and inference-free, so they default to the management-call
|
|
421
|
-
* timeout. The
|
|
422
|
-
*
|
|
423
|
-
* repository before it answers
|
|
424
|
-
*
|
|
469
|
+
* timeout. The internal raises are `crateRequestTimeoutMs`'s: the fetch-sized budget a
|
|
470
|
+
* crate route gets when its closure is a `method_ref`, because the server may clone a
|
|
471
|
+
* repository before it answers, and the execute ceiling it gets when the request
|
|
472
|
+
* carries `resources`, whose upload alone can outlast the default. Each is matched to
|
|
473
|
+
* what the request costs, not a caller-facing parameter.
|
|
425
474
|
*
|
|
426
475
|
* **These routes deliberately expose no `timeoutMs` / `signal`, and that is not an
|
|
427
476
|
* oversight to be "fixed" per route.** Automated reviewers have proposed adding them
|
|
@@ -432,8 +481,11 @@ export declare class PipelexApiClient implements MTHDSProtocol<DictPipeOutput> {
|
|
|
432
481
|
* ceiling and takes caller transport options; every extension route rides the
|
|
433
482
|
* static core. Giving one static route an override while its siblings lack one is
|
|
434
483
|
* the inconsistency.
|
|
435
|
-
* 2. The input is **bounded server-side** — the runner's `pipelex_api/limits.py` caps
|
|
436
|
-
*
|
|
484
|
+
* 2. The input is **bounded server-side** — the runner's `pipelex_api/limits.py` caps the
|
|
485
|
+
* `.mthds` files of a request and the files sent with them in `resources`, each by a
|
|
486
|
+
* count, a size per file and, for `resources`, a total, all configurable per
|
|
487
|
+
* deployment — and none of these routes runs inference. The upload those limits allow
|
|
488
|
+
* is what `crateRequestTimeoutMs` budgets for, not the server's work.
|
|
437
489
|
* 3. On the hosted path an override would be **inert**: the gateway caps responses at
|
|
438
490
|
* ~30s (see `POLL_REQUEST_TIMEOUT_MS` above), so raising `timeoutMs` would still be
|
|
439
491
|
* cut off upstream, just with a less honest error.
|
|
@@ -526,8 +578,14 @@ export declare class PipelexApiClient implements MTHDSProtocol<DictPipeOutput> {
|
|
|
526
578
|
* describes every pipe instead, and never refuses for want of an entry pipe.
|
|
527
579
|
* `include_files: true` echoes the resolved closure's `.mthds` files as `files`.
|
|
528
580
|
*
|
|
581
|
+
* Beside inline `files`, `resources` sends the files the closure's steps read, such as a
|
|
582
|
+
* `PipeDocGen` step's `template_file`, keyed by the path the step names, each as its bytes;
|
|
583
|
+
* a step whose template file was not sent makes the closure invalid. `resolve` and `codegen`
|
|
584
|
+
* take it too (see {@link CrateRequestBase}).
|
|
585
|
+
*
|
|
529
586
|
* Same 200-verdict discipline and same three-form closure selector as {@link resolve}
|
|
530
|
-
* (the request is posted
|
|
587
|
+
* (the request is posted as given, its `resources` encoded to base64, and the selector XOR
|
|
588
|
+
* and the `resources` pairing are the server's to enforce).
|
|
531
589
|
* Only a no-verdict condition throws `ApiResponseError`: a malformed selector and an
|
|
532
590
|
* over-limit file are `ValidationError` `422`s; a selection the route refuses is a
|
|
533
591
|
* `422` whose `errorType` is `EntryPipeNotFoundError` (an unknown `pipe_ref`, no entry
|
|
@@ -535,10 +593,11 @@ export declare class PipelexApiClient implements MTHDSProtocol<DictPipeOutput> {
|
|
|
535
593
|
* candidates in its `serverMessage`; a registry-form `method_ref` is a `501`; a pipe
|
|
536
594
|
* whose artifacts cannot be derived is a `500`.
|
|
537
595
|
*
|
|
538
|
-
* A `method_ref` gets the fetch-sized budget, as on the other crate routes
|
|
539
|
-
*
|
|
540
|
-
*
|
|
541
|
-
*
|
|
596
|
+
* A `method_ref` gets the fetch-sized budget, as on the other crate routes, and a
|
|
597
|
+
* request carrying `resources` the execute ceiling, since their upload alone can
|
|
598
|
+
* outlast the default. On the hosted API the gateway caps a request at about 30
|
|
599
|
+
* seconds whatever the client allows, so a cold `method_ref` clone can answer a `502`
|
|
600
|
+
* that a retry clears once the runner has cached the clone.
|
|
542
601
|
*/
|
|
543
602
|
pipeIo(request: PipeIORequest): Promise<PipeIOResponse>;
|
|
544
603
|
/**
|
|
@@ -646,7 +705,11 @@ export declare class PipelexApiClient implements MTHDSProtocol<DictPipeOutput> {
|
|
|
646
705
|
* Rows are `MethodSummary`: no `mthds`, no `python`, no `updated_at`. Reach
|
|
647
706
|
* for `getMethod(id)` when you need a method's source.
|
|
648
707
|
*
|
|
649
|
-
* `q` is applied server-side over the whole catalog, not over the page
|
|
708
|
+
* `q` is applied server-side over the whole catalog, not over the page, and so is
|
|
709
|
+
* `published` (`true` for the methods with a published version, `false` for those never
|
|
710
|
+
* published). Each row carries the method's publish state (`latest_version`,
|
|
711
|
+
* `latest_published`, `draft_digest`). Both filters run after the index read, so a page can
|
|
712
|
+
* come back empty and still carry a `nextCursor`: keep following it until it is `null`.
|
|
650
713
|
*/
|
|
651
714
|
listMethods(query?: ListMethodsQuery): Promise<MethodPage>;
|
|
652
715
|
/**
|
|
@@ -667,6 +730,11 @@ export declare class PipelexApiClient implements MTHDSProtocol<DictPipeOutput> {
|
|
|
667
730
|
* TRUNCATED list with no error — precisely the bug paging was introduced to
|
|
668
731
|
* remove. If you truly want an array, `Array.fromAsync` makes that your
|
|
669
732
|
* explicit choice.
|
|
733
|
+
*
|
|
734
|
+
* It keeps going **through an empty page that carries a cursor**: under `q` or `published`
|
|
735
|
+
* such a page means "nothing matched in the slice just read", not "done". It stops on a
|
|
736
|
+
* `null` cursor or on a cursor the server failed to advance, and throws
|
|
737
|
+
* `PagingNotTerminatingError` past a page ceiling no real catalog reaches.
|
|
670
738
|
*/
|
|
671
739
|
iterateMethods(query?: Omit<ListMethodsQuery, "cursor">): AsyncGenerator<MethodSummary, void, undefined>;
|
|
672
740
|
/**
|
|
@@ -965,7 +1033,8 @@ export declare class PipelexApiClient implements MTHDSProtocol<DictPipeOutput> {
|
|
|
965
1033
|
* Name the method exactly one of three ways, all server-resolved through the
|
|
966
1034
|
* one `pipeIo` call this composes:
|
|
967
1035
|
*
|
|
968
|
-
* - `files` — the inline MTHDS closure
|
|
1036
|
+
* - `files` — the inline MTHDS closure, with the `resources` its steps read
|
|
1037
|
+
* (a `PipeDocGen` step's `template_file`), keyed by the path a step names;
|
|
969
1038
|
* - `method_ref` — a published method's address, fetched by the runner;
|
|
970
1039
|
* - `method_id` — a stored method's catalog id, resolved by the platform
|
|
971
1040
|
* (hosted only; requires an API key).
|
|
@@ -976,8 +1045,11 @@ export declare class PipelexApiClient implements MTHDSProtocol<DictPipeOutput> {
|
|
|
976
1045
|
* position is a fact of the method, never a guess from the value's shape. It
|
|
977
1046
|
* needs an API serving `POST /v1/pipe-io`. See `docs/input-preparation.md`.
|
|
978
1047
|
*
|
|
979
|
-
*
|
|
980
|
-
*
|
|
1048
|
+
* A value at a file input that cannot be a file, such as a number or a
|
|
1049
|
+
* `data:` URL that does not decode, throws `InvalidInputValueError`, naming the
|
|
1050
|
+
* input. With `allowUploads: false` it uploads nothing and reads no file: a
|
|
1051
|
+
* value that would need an upload throws `UploadNotAllowedError`, naming the
|
|
1052
|
+
* input too.
|
|
981
1053
|
*/
|
|
982
1054
|
prepareInputs(request: PrepareInputsRequest): Promise<PreparedInputs>;
|
|
983
1055
|
/**
|
|
@@ -1002,6 +1074,13 @@ export declare class PipelexApiClient implements MTHDSProtocol<DictPipeOutput> {
|
|
|
1002
1074
|
* conditions, so a bounded page genuinely reads less. They are INSTANTS,
|
|
1003
1075
|
* not days — see `ListRunsQuery`.
|
|
1004
1076
|
*
|
|
1077
|
+
* `createdBy: "me"` keeps the caller's own runs and `status` the runs in any of the given
|
|
1078
|
+
* statuses, sent as `created_by=me` and one repeated `status=` parameter per status. Both are
|
|
1079
|
+
* filters applied after the index read, so a filtered page can hold fewer runs than `limit`,
|
|
1080
|
+
* or none, and still carry a `nextCursor`: an empty page is not the end, a `null` cursor is.
|
|
1081
|
+
* An empty `status` list, or a name that is no `RunStatus`, is a `RequestArgumentError`
|
|
1082
|
+
* before any request.
|
|
1083
|
+
*
|
|
1005
1084
|
* Takes a bare catalog id: the history files the runs of every version and
|
|
1006
1085
|
* of the draft together under it, so `mt_…@3` names no history of its own
|
|
1007
1086
|
* and the platform refuses it with a `400`. Strip a suffix with
|
|
@@ -1031,6 +1110,11 @@ export declare class PipelexApiClient implements MTHDSProtocol<DictPipeOutput> {
|
|
|
1031
1110
|
* when to stop, and only one page is ever in memory. If you truly want an
|
|
1032
1111
|
* array, `Array.fromAsync` makes that your explicit choice.
|
|
1033
1112
|
*
|
|
1113
|
+
* It keeps going **through an empty page that carries a cursor**: under `createdBy` or
|
|
1114
|
+
* `status` such a page means "nothing matched in the slice just read", not "done". It stops on
|
|
1115
|
+
* a `null` cursor or on a cursor the server failed to advance, and throws
|
|
1116
|
+
* `PagingNotTerminatingError` past a page ceiling no real history reaches.
|
|
1117
|
+
*
|
|
1034
1118
|
* Takes a bare catalog id, as `listRuns` does.
|
|
1035
1119
|
*/
|
|
1036
1120
|
iterateRuns(methodId: string, query?: Omit<ListRunsQuery, "cursor">): AsyncGenerator<RunHistoryItem, void, undefined>;
|