@pipelex/sdk 0.41.0 → 0.43.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.
@@ -0,0 +1,127 @@
1
+ /**
2
+ * JSON whose integers stay exact.
3
+ *
4
+ * JavaScript reads every JSON number as a double, so an integer past `Number.MAX_SAFE_INTEGER`
5
+ * (2^53 - 1) reads rounded, `12345678901234567891` as `12345678901234567000`, and is written back
6
+ * rounded. `parseExactJson` reads such an integer as a `bigint` holding its exact digits instead,
7
+ * and `stringifyExactJson` writes a `bigint` back as those digits where `JSON.stringify` throws;
8
+ * everything else reads and writes exactly as `JSON.parse` and `JSON.stringify` read and write it,
9
+ * since both are those very functions. A number with a fraction or an exponent stays a double:
10
+ * `3.0` reads as `3`, as it does everywhere in JavaScript, and is written back as `3`.
11
+ *
12
+ * Both rest on the JSON source-text proposal, which every runtime this package supports provides:
13
+ * the reader on the source text `JSON.parse` hands its reviver (`context.source`), the writer on
14
+ * `JSON.rawJSON`. On a runtime without them, neither ever rounds: the reader refuses a number it
15
+ * cannot read exactly with `ExactJsonUnsupportedError`, and the writer refuses a `bigint` with the
16
+ * `TypeError` `JSON.stringify` throws for one.
17
+ *
18
+ * The client reads with `parseExactJson` every answer that carries a person's data, a method
19
+ * example's inputs and a run's inputs, outputs and working memory, and writes every request body
20
+ * with `stringifyExactJson`, so such data goes back to the platform digit for digit. The barrel
21
+ * exports both and the error, for a caller that shows such data as JSON text or reads it back from
22
+ * it. This module imports nothing but a type.
23
+ */
24
+ /** An integer as JSON spells one: a sign and digits, with no fraction and no exponent. */
25
+ const INTEGER_TOKEN = /^-?\d+$/;
26
+ /**
27
+ * A run of 16 digits. Every integer past the safe range spells at least that many, the smallest
28
+ * being `9007199254740992`, so a text without one holds no such integer, and `JSON.parse` reads
29
+ * it exactly with no reviver to call. A run inside a string only costs the reviver's calls.
30
+ */
31
+ const LONG_DIGIT_RUN = /\d{16}/;
32
+ /** `JSON`, with the `rawJSON` the TypeScript library this package compiles against does not declare. */
33
+ const JSON_WITH_RAW = JSON;
34
+ /**
35
+ * Thrown by `parseExactJson` on a runtime whose `JSON.parse` does not hand a reviver the source
36
+ * text of a value, for a text holding a number it then cannot read exactly: one past
37
+ * `Number.MAX_SAFE_INTEGER` that reads as a whole number, or as `Infinity`. Without the source
38
+ * text, such a number cannot be told from a float of the same value, so the reader refuses it
39
+ * rather than read it rounded. Every runtime this package supports hands the source text.
40
+ *
41
+ * Outside the `PipelexRequestError` family, since nothing was requested, it declares the verdict
42
+ * every SDK error carries itself, so `errorVerdictOf` reads it like any other: `config`, not
43
+ * retryable, since running on a runtime the package supports is what fixes it.
44
+ */
45
+ export class ExactJsonUnsupportedError extends Error {
46
+ /** Whether asking again can succeed: never, on this runtime. */
47
+ retryable = false;
48
+ /** Who can fix it: the environment, by moving to a runtime the package supports. */
49
+ errorDomain = "config";
50
+ /** Reading JSON starts no run. */
51
+ runMayHaveStarted = false;
52
+ constructor(message) {
53
+ super(message);
54
+ this.name = "ExactJsonUnsupportedError";
55
+ }
56
+ }
57
+ /**
58
+ * Read a JSON text as `JSON.parse` reads it, except that an integer past `Number.MAX_SAFE_INTEGER`
59
+ * in either direction is a `bigint` holding its exact digits. Throws the `SyntaxError`
60
+ * `JSON.parse` throws for a text that is not JSON, and `ExactJsonUnsupportedError` on a runtime
61
+ * that cannot read such an integer exactly.
62
+ */
63
+ export function parseExactJson(text) {
64
+ return LONG_DIGIT_RUN.test(text) ? JSON.parse(text, readIntegerExactly) : JSON.parse(text);
65
+ }
66
+ /**
67
+ * Write a value as `JSON.stringify` writes it, `space` indenting as its own does, except that a
68
+ * `bigint` is written as its exact digits rather than refused. It is one `JSON.stringify` call,
69
+ * whose replacer writes each `bigint` as raw JSON text, so every getter and every `toJSON` in the
70
+ * value runs once, and whatever one of them throws propagates as thrown. A `toJSON` a `bigint`
71
+ * inherits, such as the common polyfill `BigInt.prototype.toJSON`, is passed over: the `bigint`
72
+ * is still written as its digits, not as what that `toJSON` makes of it, unless a getter returns
73
+ * it, since reading it again would run the getter twice. That rests on `JSON.rawJSON`, which
74
+ * every runtime this package supports provides; on one without it, a `bigint` is refused with a
75
+ * `TypeError`, as `JSON.stringify` refuses it, and never written rounded. Any other failure, a
76
+ * cycle for instance, is the `TypeError` `JSON.stringify` throws for it.
77
+ */
78
+ export function stringifyExactJson(value, space) {
79
+ // `toJSON` runs before the replacer, so under such a `toJSON` the replacer is handed what it
80
+ // made of a `bigint`, a string most often, and finds the `bigint` in the holder instead.
81
+ const bigIntHasToJson = typeof BigInt.prototype.toJSON === "function";
82
+ return JSON.stringify(value, function writeBigIntExactly(key, item) {
83
+ if (typeof item === "bigint")
84
+ return rawBigInt(item);
85
+ if (!bigIntHasToJson)
86
+ return item;
87
+ const held = ownDataValue(this, key);
88
+ return typeof held === "bigint" ? rawBigInt(held) : item;
89
+ }, space);
90
+ }
91
+ /**
92
+ * The reviver of `parseExactJson`: a number past the safe range spelled as an integer becomes a
93
+ * `bigint` of its source text, which also covers one too long for a double, which `JSON.parse`
94
+ * reads as `Infinity`. Every other value is returned as `JSON.parse` read it, so an object is
95
+ * built as `JSON.parse` builds one, `__proto__` and repeated keys included.
96
+ */
97
+ function readIntegerExactly(_key, value, context) {
98
+ if (typeof value !== "number" || Number.isSafeInteger(value))
99
+ return value;
100
+ const source = context?.source;
101
+ if (typeof source === "string")
102
+ return INTEGER_TOKEN.test(source) ? BigInt(source) : value;
103
+ // No source text: a fraction stays the double it is, but a whole number past the safe range,
104
+ // `Infinity` included, may have been spelled as an integer this read would round.
105
+ if (Number.isFinite(value) && !Number.isInteger(value))
106
+ return value;
107
+ throw new ExactJsonUnsupportedError(`This runtime's JSON.parse gives a reviver no source text, so the number read as ${value} ` +
108
+ "cannot be read exactly.");
109
+ }
110
+ /** A `bigint` as the raw JSON text of its exact digits, refused on a runtime without `rawJSON`. */
111
+ function rawBigInt(value) {
112
+ if (typeof JSON_WITH_RAW.rawJSON !== "function") {
113
+ throw new TypeError(`This runtime has no JSON.rawJSON, so the bigint ${value.toString()} cannot be written ` +
114
+ "as its exact digits.");
115
+ }
116
+ return JSON_WITH_RAW.rawJSON(value.toString());
117
+ }
118
+ /**
119
+ * The value `holder` holds under `key` as an own data property, read from its descriptor so that
120
+ * no getter runs again, or `undefined` for an accessor or no such property.
121
+ */
122
+ function ownDataValue(holder, key) {
123
+ if (typeof holder !== "object" || holder === null)
124
+ return undefined;
125
+ return Object.getOwnPropertyDescriptor(holder, key)?.value;
126
+ }
127
+ //# sourceMappingURL=exact-json.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exact-json.js","sourceRoot":"","sources":["../src/exact-json.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -12,11 +12,12 @@ export * from "mthds/protocol";
12
12
  export { PipelexApiClient, DEFAULT_API_BASE_URL, isGatewayCutOff } from "./client.js";
13
13
  export { buildUserAgent, validateAppInfo, MAX_USER_AGENT_LENGTH } from "./user-agent.js";
14
14
  export type { AppInfo, RuntimeInfo } from "./user-agent.js";
15
- export type { MthdsFile, PipelexApiRunExtensions, PipelexHostedRunExtensions, PipelexRunOptions, PipelexStartOptions, ValidateMethodSelector, ValidateFilesOptions, ValidateOptions, PipelexApiClientOptions, } from "./client.js";
15
+ export type { MthdsFile, PipelexApiRunExtensions, PipelexHostedRunExtensions, PipelexRunOptions, PipelexStartOptions, PipelexStartRequestOptions, ValidateMethodSelector, ValidateFilesOptions, ValidateOptions, PipelexApiClientOptions, } from "./client.js";
16
16
  export type { BundleResourceBytes, BundleResources } from "./bundle-resources.js";
17
17
  export { methodSourceToContents } from "./method-source.js";
18
18
  export { parseMethodSelector } from "./method-selector.js";
19
19
  export type { ParsedMethodSelector } from "./method-selector.js";
20
+ export { ExactJsonUnsupportedError, parseExactJson, stringifyExactJson } from "./exact-json.js";
20
21
  export { PipelexExecuteResult, resultsFromExecute } from "./execute-result.js";
21
22
  export type { UploadableAsset, UploadFileOptions, UploadRecord } from "./upload.js";
22
23
  export { uploadWithGrant } from "./upload-grant.js";
@@ -28,11 +29,11 @@ export type { ArtifactItemError, ArtifactLocation, ArtifactScope, BulkResolveSto
28
29
  export type { DiagnosticKind, DiagnosticRange, Diagnostic, LintResponse, FormatResponse, DictStuff, DictWorkingMemory, DictPipeOutput, DictRunResultExecute, MethodProvenance, PipelexRunResultStart, PipelexHostedToolingExtensions, DryRunStatus, ValidatedPipeEntry, LiftablePipeEntry, PipelexValidationReport, PipelexInvalidReport, PipelexValidationResult, ValidationErrorCategory, ValidationErrorItem, FixSafety, FixOpKind, TomlScalar, TomlValue, FixValue, SetKeyOp, EnsureTableOp, DeleteKeyOp, DeleteTableOp, RenameTableKeyOp, MoveKeyOp, RemapValueOp, FixOp, SuggestedFix, MthdsFileItem, CrateRequestBase, CrateInvalidReport, GeneratedArtifact, ResolveRequest, ResolveValidReport, ResolveResponse, CodegenKind, CodegenTarget, CodegenRequest, CodegenValidReport, CodegenResponse, PipeIORequest, PipeIOValidReport, PipeIOResponse, ModelCheckCategory, ModelReferenceKind, ModelReferenceResolution, ModelReferenceMatchBase, PresetMatch, AliasMatch, WaterfallMatch, HandleMatch, ModelReferenceMatch, ModelReferenceVerdictBase, PresetReferenceVerdict, AliasReferenceVerdict, WaterfallReferenceVerdict, HandleReferenceVerdict, ModelReferenceVerdict, } from "./models.js";
29
30
  export { runCodegenCheck, isStampableArtifactPath, STAMPABLE_ARTIFACT_SUFFIXES, CodegenLockError, } from "./codegen-check.js";
30
31
  export type { CodegenCheckInput, CodegenCheckReport, CodegenDrift, CodegenDriftCategory, CodegenTreeFile, } from "./codegen-check.js";
31
- export type { UserProfile, ListMethodsQuery, ListMethodVersionsQuery, MethodData, MethodDeletionAccepted, MethodDeletionState, MethodDraftInput, MethodPage, MethodPublished, MethodPublishInput, MethodPublishOutcome, MethodPublishRefusalReason, MethodPublishRefused, MethodPublishResult, MethodPublishUnchanged, MethodRenameInput, MethodSummary, MethodVersion, MethodVersionPage, MethodVersionSummary, MethodWriteInput, Membership, MembershipsResponse, SubscriptionResponse, PlanView, InvoiceView, CheckoutResponse, ChangePlanResponse, BillingPortalResponse, PipelexApiKey, PipelexApiKeyCreated, PipelexApiKeyList, OnboardingRole, OnboardingCurrentTool, OnboardingInputType, OnboardingHeardFrom, OnboardingSubmission, ResolvedStorageUrl, UploadInput, UploadedFile, UploadGrantInput, UploadGrant, PipeStatus, ListRunsQuery, PipelineRun, RunDetail, RunHistoryItem, RunPage, UpdateRunInput, } from "./product-models.js";
32
+ export type { UserProfile, ListMethodExamplesQuery, ListMethodsQuery, ListMethodVersionsQuery, MethodData, MethodDeletionAccepted, MethodDeletionState, MethodDraftInput, MethodExample, MethodExampleCreateInput, MethodExampleLatestRunInput, MethodExampleLatestRunOutcome, MethodExampleLatestRunRecorded, MethodExampleLatestRunResult, MethodExampleLatestRunStale, MethodExamplePage, MethodExampleUpdateInput, MethodPage, MethodPublished, MethodPublishInput, MethodPublishOutcome, MethodPublishRefusalReason, MethodPublishRefused, MethodPublishResult, MethodPublishUnchanged, MethodRenameInput, MethodSummary, MethodVersion, MethodVersionPage, MethodVersionSummary, MethodWriteInput, Membership, MembershipsResponse, SubscriptionResponse, PlanView, InvoiceView, CheckoutResponse, ChangePlanResponse, BillingPortalResponse, PipelexApiKey, PipelexApiKeyCreated, PipelexApiKeyList, OnboardingRole, OnboardingCurrentTool, OnboardingInputType, OnboardingHeardFrom, OnboardingSubmission, ResolvedStorageUrl, UploadInput, UploadedFile, UploadGrantInput, UploadGrant, PipeStatus, ListRunsQuery, PipelineRun, RunDetail, RunHistoryItem, RunPage, UpdateRunInput, } from "./product-models.js";
32
33
  export { isTerminalRunStatus, isSuccessRunStatus, RUN_RESULT_ARTIFACTS } from "./runs.js";
33
34
  export type { DegradationReason, GetRunResultOptions, RunDegradation, RunResultArtifact, RunStatus, RunPublic, RunRead, RunResults, RunResultState, StartAndWaitForResultOptions, TokensUsageRecord, WaitForResultOptions, } from "./runs.js";
34
35
  export { summarizeUsage } from "./usage.js";
35
36
  export type { PipeUsageSummary, RunUsagePair, UsageSummary, UsageSummaryState, UsageTokenTotals, } from "./usage.js";
36
37
  export { PipelexRequestError, errorVerdictOf, runMayHaveStartedOf, RequestArgumentError, ApiResponseError, ApiUnreachableError, MissingMainStuffError, PagingNotTerminatingError, PipelineExecuteTimeoutError, RunFailedError, RunTimeoutError, RunStillRunningError, RunLifecycleUnavailableError, InputPreparationError, EmptyMethodSourceError, InvalidLocalSourceError, InvalidInputValueError, UploadNotAllowedError, MethodLoadError, RejectedAssetError, UnsupportedUploadCapabilityError, UploadAuthenticationError, UploadTransportError, ArtifactOperationError, ArtifactAuthenticationError, ArtifactFetchError, ScopeUnavailableError, } from "./errors.js";
37
- export type { ApiResponseErrorOptions, ErrorDomain, ErrorVerdict, MethodErrorCode, RejectedAssetCode, UploadNotAllowedKind, UploadTransportCode, } from "./errors.js";
38
+ export type { ApiResponseErrorOptions, ErrorDomain, ErrorVerdict, IdempotencyErrorCode, MethodErrorCode, RejectedAssetCode, UploadNotAllowedKind, UploadTransportCode, } from "./errors.js";
38
39
  export type { FieldError, MigrationErrorBlock, ProblemDetails, ProviderErrorMetadata, RunErrorReport, UserAction, } from "./error-models.js";
package/dist/index.js CHANGED
@@ -23,6 +23,12 @@ export { buildUserAgent, validateAppInfo, MAX_USER_AGENT_LENGTH } from "./user-a
23
23
  export { methodSourceToContents } from "./method-source.js";
24
24
  // A method selector (`mt_…`, `mt_…@<n>`, `mt_…@draft`) → its bare id and the version it names.
25
25
  export { parseMethodSelector } from "./method-selector.js";
26
+ // JSON whose integers stay exact: the reader of the answers carrying a person's data (a method
27
+ // example's inputs, a run's inputs, outputs and working memory), which keeps an integer past
28
+ // `Number.MAX_SAFE_INTEGER` as a `bigint`, and the writer of every request body, which writes it
29
+ // back as its digits — for a caller showing such data as JSON text. The error is the reader's
30
+ // refusal on a runtime that cannot read such an integer exactly.
31
+ export { ExactJsonUnsupportedError, parseExactJson, stringifyExactJson } from "./exact-json.js";
26
32
  // The blocking `execute()` result — a `DictRunResultExecute` with a resolved `.main_stuff` — and
27
33
  // the lift from it onto `RunResults`, for a caller who drives `execute()` itself.
28
34
  export { PipelexExecuteResult, resultsFromExecute } from "./execute-result.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,6FAA6F;AAC7F,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,oFAAoF;AACpF,kFAAkF;AAClF,mFAAmF;AACnF,wBAAwB;AACxB,cAAc,gBAAgB,CAAC;AAE/B,wEAAwE;AACxE,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACtF,sFAAsF;AACtF,yFAAyF;AACzF,2EAA2E;AAC3E,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAezF,+FAA+F;AAC/F,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,+FAA+F;AAC/F,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAG3D,iGAAiG;AACjG,kFAAkF;AAClF,OAAO,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAK/E,yFAAyF;AACzF,sEAAsE;AACtE,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AASpD,+FAA+F;AAC/F,0EAA0E;AAC1E,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAErD,uEAAuE;AACvE,wFAAwF;AACxF,0FAA0F;AAC1F,iFAAiF;AACjF,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,gBAAgB,EAChB,sBAAsB,EACtB,qBAAqB,EACrB,0BAA0B,EAC1B,2BAA2B,EAC3B,gCAAgC,EAChC,4BAA4B,GAC7B,MAAM,gBAAgB,CAAC;AAmFxB,+EAA+E;AAC/E,4EAA4E;AAC5E,iFAAiF;AACjF,0EAA0E;AAC1E,OAAO,EACL,eAAe,EACf,uBAAuB,EACvB,2BAA2B,EAC3B,gBAAgB,GACjB,MAAM,oBAAoB,CAAC;AA8D5B,wEAAwE;AACxE,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAgB1F,oFAAoF;AACpF,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAS5C,+EAA+E;AAC/E,gGAAgG;AAChG,wDAAwD;AACxD,OAAO,EACL,mBAAmB,EACnB,cAAc,EACd,mBAAmB,EACnB,oBAAoB,EACpB,gBAAgB,EAChB,mBAAmB,EACnB,qBAAqB,EACrB,yBAAyB,EACzB,2BAA2B,EAC3B,cAAc,EACd,eAAe,EACf,oBAAoB,EACpB,4BAA4B,EAC5B,qBAAqB,EACrB,sBAAsB,EACtB,uBAAuB,EACvB,sBAAsB,EACtB,qBAAqB,EACrB,eAAe,EACf,kBAAkB,EAClB,gCAAgC,EAChC,yBAAyB,EACzB,oBAAoB,EACpB,sBAAsB,EACtB,2BAA2B,EAC3B,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,6FAA6F;AAC7F,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,oFAAoF;AACpF,kFAAkF;AAClF,mFAAmF;AACnF,wBAAwB;AACxB,cAAc,gBAAgB,CAAC;AAE/B,wEAAwE;AACxE,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACtF,sFAAsF;AACtF,yFAAyF;AACzF,2EAA2E;AAC3E,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAgBzF,+FAA+F;AAC/F,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,+FAA+F;AAC/F,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAE3D,+FAA+F;AAC/F,6FAA6F;AAC7F,iGAAiG;AACjG,8FAA8F;AAC9F,iEAAiE;AACjE,OAAO,EAAE,yBAAyB,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAEhG,iGAAiG;AACjG,kFAAkF;AAClF,OAAO,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAK/E,yFAAyF;AACzF,sEAAsE;AACtE,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AASpD,+FAA+F;AAC/F,0EAA0E;AAC1E,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAErD,uEAAuE;AACvE,wFAAwF;AACxF,0FAA0F;AAC1F,iFAAiF;AACjF,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,gBAAgB,EAChB,sBAAsB,EACtB,qBAAqB,EACrB,0BAA0B,EAC1B,2BAA2B,EAC3B,gCAAgC,EAChC,4BAA4B,GAC7B,MAAM,gBAAgB,CAAC;AAmFxB,+EAA+E;AAC/E,4EAA4E;AAC5E,iFAAiF;AACjF,0EAA0E;AAC1E,OAAO,EACL,eAAe,EACf,uBAAuB,EACvB,2BAA2B,EAC3B,gBAAgB,GACjB,MAAM,oBAAoB,CAAC;AAwE5B,wEAAwE;AACxE,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAgB1F,oFAAoF;AACpF,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAS5C,+EAA+E;AAC/E,gGAAgG;AAChG,wDAAwD;AACxD,OAAO,EACL,mBAAmB,EACnB,cAAc,EACd,mBAAmB,EACnB,oBAAoB,EACpB,gBAAgB,EAChB,mBAAmB,EACnB,qBAAqB,EACrB,yBAAyB,EACzB,2BAA2B,EAC3B,cAAc,EACd,eAAe,EACf,oBAAoB,EACpB,4BAA4B,EAC5B,qBAAqB,EACrB,sBAAsB,EACtB,uBAAuB,EACvB,sBAAsB,EACtB,qBAAqB,EACrB,eAAe,EACf,kBAAkB,EAClB,gCAAgC,EAChC,yBAAyB,EACzB,oBAAoB,EACpB,sBAAsB,EACtB,2BAA2B,EAC3B,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,aAAa,CAAC"}
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Pipelex-product wire models — the snake_case JSON shapes the hosted-product
3
- * routes (`/v1/me`, `/v1/methods`, `/v1/organizations`, `/v1/billing/*`,
3
+ * routes (`/v1/me`, `/v1/methods` and its examples, `/v1/organizations`, `/v1/billing/*`,
4
4
  * `/v1/pipelex-api-keys`, `/v1/onboarding/submit`,
5
5
  * `/v1/resolve-storage-url`, `/v1/upload`, `/v1/upload/grant`, `/v1/runs`) speak.
6
6
  *
@@ -342,6 +342,135 @@ export interface MethodVersionPage {
342
342
  items: MethodVersionSummary[];
343
343
  nextCursor: string | null;
344
344
  }
345
+ /**
346
+ * One saved example of a method — what `createMethodExample`, `getMethodExample`,
347
+ * `updateMethodExample` and both arms of `recordMethodExampleLatestRun` answer, and a row of
348
+ * `listMethodExamples`.
349
+ */
350
+ export interface MethodExample {
351
+ /** The example's id, `ex_…`, minted by the platform. */
352
+ example_id: string;
353
+ /** The bare id of the method the example belongs to. */
354
+ method_id: string;
355
+ /** The example's name, 1 to 200 characters and not blank. */
356
+ name: string;
357
+ /**
358
+ * The inputs a run of the example sends, a JSON object, which the platform stores and answers
359
+ * exactly as they were saved. **An integer past `Number.MAX_SAFE_INTEGER`, in either
360
+ * direction and at any depth, reads as a `bigint`** holding its exact digits, since a double
361
+ * would round it; the client sends a `bigint` back as those digits, to `updateMethodExample` or
362
+ * as a run's inputs, so such inputs go back unchanged. `JSON.stringify` throws on a `bigint`:
363
+ * show the inputs as JSON text with `stringifyExactJson`, and read edited text back with
364
+ * `parseExactJson`. Every other number reads as a double, so a float with no fractional part,
365
+ * `3.0`, reads as `3` and goes back as `3`; the platform compares inputs as canonical JSON, so
366
+ * inputs holding one, sent back unchanged to `updateMethodExample`, raise `input_revision` and
367
+ * clear `latest_run_id`. Inputs saved from JavaScript never hold one, since JavaScript cannot
368
+ * write it; inputs another client saved can.
369
+ */
370
+ inputs: Record<string, unknown>;
371
+ /**
372
+ * Starts at 1 and rises by one each time the inputs change. Send it, as read when the run
373
+ * was started, to `recordMethodExampleLatestRun`.
374
+ */
375
+ input_revision: number;
376
+ /**
377
+ * The latest run of the current inputs, `null` when none was recorded since they last
378
+ * changed. It may name a run deleted since, which then reads as not found.
379
+ */
380
+ latest_run_id: string | null;
381
+ /** The canonical id of the member who saved the example; it confers nothing. */
382
+ created_by_user_id: string;
383
+ /** ISO-8601 UTC instant of the example's creation. */
384
+ created_at: string;
385
+ /** ISO-8601 UTC instant of its last change: its name, its inputs or its latest run. */
386
+ updated_at: string;
387
+ }
388
+ /** The create — `createMethodExample`, `POST /v1/methods/{id}/examples`. */
389
+ export interface MethodExampleCreateInput {
390
+ /** The example's name, 1 to 200 characters and not blank. */
391
+ name: string;
392
+ /**
393
+ * The inputs a run of the example sends, a JSON object; a `bigint` in them is sent as its
394
+ * exact digits.
395
+ */
396
+ inputs: Record<string, unknown>;
397
+ /**
398
+ * A run of this method that used exactly these inputs, recorded as the example's latest run
399
+ * at revision 1 — the run a person saves as an example. Omitted, or `null`, the example has no
400
+ * latest run; an empty string is refused before anything is sent.
401
+ */
402
+ run_id?: string | null;
403
+ }
404
+ /**
405
+ * The edit — `updateMethodExample`, `PATCH /v1/methods/{id}/examples/{example_id}`: a new name,
406
+ * new inputs, or both, and at least one of them. An omitted field keeps the stored value.
407
+ */
408
+ export interface MethodExampleUpdateInput {
409
+ /** The example's new name, 1 to 200 characters and not blank. */
410
+ name?: string;
411
+ /**
412
+ * The example's new inputs. Inputs that differ from the stored ones raise `input_revision`
413
+ * by one and clear `latest_run_id`; the same inputs, their keys in another order included,
414
+ * change nothing. A `bigint` in them is sent as its exact digits. Send them only when they
415
+ * changed: inputs read back that held `3.0` differ once JavaScript has read them, as `3` (see
416
+ * `MethodExample.inputs`).
417
+ */
418
+ inputs?: Record<string, unknown>;
419
+ }
420
+ /** The latest-run write — `recordMethodExampleLatestRun`. */
421
+ export interface MethodExampleLatestRunInput {
422
+ /** A run of this method that used the example's inputs. */
423
+ run_id: string;
424
+ /**
425
+ * The example's `input_revision` whose inputs the run used, as the caller read it when it
426
+ * started the run. The run is recorded only while the example still holds that revision.
427
+ */
428
+ input_revision: number;
429
+ }
430
+ /** What a latest-run write did — the discriminant of `MethodExampleLatestRunResult`. */
431
+ export type MethodExampleLatestRunOutcome = "recorded" | "stale";
432
+ /** The run is now the example's latest; `example` is the example as it now stands. */
433
+ export interface MethodExampleLatestRunRecorded {
434
+ outcome: "recorded";
435
+ example: MethodExample;
436
+ }
437
+ /**
438
+ * The run used inputs the example no longer holds, and nothing was written; `example` is the
439
+ * example as it stands, with its current revision and latest run.
440
+ */
441
+ export interface MethodExampleLatestRunStale {
442
+ outcome: "stale";
443
+ example: MethodExample;
444
+ }
445
+ /**
446
+ * The answer of `recordMethodExampleLatestRun`, a `200` discriminated on `outcome`. A stale run
447
+ * is the expected end of a run that outlasted an edit of the example's inputs, a verdict about
448
+ * the run rather than a failed request, so it is answered rather than thrown. Branch on
449
+ * `outcome`, never on the status: an unknown example, a run that is not the method's or a
450
+ * method being deleted are thrown as `ApiResponseError` instead.
451
+ */
452
+ export type MethodExampleLatestRunResult = MethodExampleLatestRunRecorded | MethodExampleLatestRunStale;
453
+ /** Query for one page of a method's examples. */
454
+ export interface ListMethodExamplesQuery {
455
+ /**
456
+ * Page size, from 1 to 100; the API defaults to 50 and refuses a `limit` outside that range
457
+ * with a `422`.
458
+ */
459
+ limit?: number;
460
+ /** Opaque `nextCursor` from the previous page. */
461
+ cursor?: string;
462
+ }
463
+ /**
464
+ * One page of a method's examples, oldest first, inputs included.
465
+ *
466
+ * `nextCursor` is opaque — pass it straight back to `listMethodExamples` to continue; `null`
467
+ * means this was the last page. Examples are read whole on the server, and a read stops at
468
+ * 1 MB, so a page may be short while `nextCursor` is set; `iterateMethodExamples` follows it.
469
+ */
470
+ export interface MethodExamplePage {
471
+ items: MethodExample[];
472
+ nextCursor: string | null;
473
+ }
345
474
  export interface Membership {
346
475
  org_id: string;
347
476
  /** Null for the implicit personal org (no backing WorkOS organization). */
@@ -574,7 +703,12 @@ export interface RunDetail extends PipelineRun {
574
703
  * the protocol's validate call takes and echoes back. A single-file method
575
704
  * is an array of one. */
576
705
  mthds_contents?: string[] | null;
577
- /** The inputs the run was started with, as sent. */
706
+ /**
707
+ * The inputs the run was started with, as sent, an integer past `Number.MAX_SAFE_INTEGER` read
708
+ * as a `bigint` holding its exact digits, so the inputs passed back to `start` run what the run
709
+ * ran. Show them as JSON text with `stringifyExactJson`, since `JSON.stringify` throws on a
710
+ * `bigint`.
711
+ */
578
712
  inputs?: Record<string, unknown> | null;
579
713
  /**
580
714
  * The id of the request that started the run — the one to quote to support, and the one the
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Pipelex-product wire models — the snake_case JSON shapes the hosted-product
3
- * routes (`/v1/me`, `/v1/methods`, `/v1/organizations`, `/v1/billing/*`,
3
+ * routes (`/v1/me`, `/v1/methods` and its examples, `/v1/organizations`, `/v1/billing/*`,
4
4
  * `/v1/pipelex-api-keys`, `/v1/onboarding/submit`,
5
5
  * `/v1/resolve-storage-url`, `/v1/upload`, `/v1/upload/grant`, `/v1/runs`) speak.
6
6
  *
package/dist/runs.d.ts CHANGED
@@ -289,7 +289,9 @@ export interface RunResults {
289
289
  * a multiple output the envelope `{ items: [...] }` the runtime's `ListContent` serialises to,
290
290
  * and a native is wrapped too (`{ text }`, `{ number }`). It may be a valid empty value — an
291
291
  * empty `items`, an empty `text` — but it is never null. It is absent only from a read whose
292
- * `artifacts` selection left it out. See `docs/run-results.md`.
292
+ * `artifacts` selection left it out. An integer past `Number.MAX_SAFE_INTEGER` in it, as anywhere
293
+ * in the results, is a `bigint` holding its exact digits (`docs/exact-integers.md`). See
294
+ * `docs/run-results.md`.
293
295
  */
294
296
  main_stuff?: unknown;
295
297
  /**
package/dist/runs.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"runs.js","sourceRoot":"","sources":["../src/runs.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"runs.js","sourceRoot":"","sources":["../src/runs.ts"],"names":[],"mappings":"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"}
package/dist/version.d.ts CHANGED
@@ -3,4 +3,4 @@
3
3
  * `User-Agent` without importing the public barrel. Kept in sync with
4
4
  * `package.json` — enforced by `tests/index.test.ts`.
5
5
  */
6
- export declare const SDK_VERSION = "0.41.0";
6
+ export declare const SDK_VERSION = "0.43.0";
package/dist/version.js CHANGED
@@ -3,5 +3,5 @@
3
3
  * `User-Agent` without importing the public barrel. Kept in sync with
4
4
  * `package.json` — enforced by `tests/index.test.ts`.
5
5
  */
6
- export const SDK_VERSION = "0.41.0";
6
+ export const SDK_VERSION = "0.43.0";
7
7
  //# sourceMappingURL=version.js.map
@@ -44,6 +44,7 @@ The map has a second entry, **`@pipelex/sdk/upload`** (`dist/upload-grant.js`),
44
44
 
45
45
  - Base URL from env (default `https://api.pipelex.com`); every route under `/v1/*`.
46
46
  - Auth: `Authorization: Bearer <token>`; organization resolved from the JWT `org_id` claim, not a header.
47
+ - A caller's id enters a route's path through one guard, `idPathSegment` in `client.ts`, as one percent-encoded segment: a method's, an example's, a run's, an organization's or an API key's. `encodeURIComponent` leaves the dot alone, and the URL resolves a dot segment before the request leaves, so an id of `.` or `..` would address another route (an example id `..` deleting the method itself), and an empty one the route above it. Each is a `RequestArgumentError` before anything is sent, as is an id that is not a string and one holding a lone surrogate, which has no UTF-8 spelling and so no percent-encoding. The non-empty check is `requireNonEmptyId`, which the run ids an example write records go through too.
47
48
  - A diagnostic verdict (e.g. `/v1/validate`) is a `200` discriminated on a body field (`is_valid`); non-2xx is reserved for "no verdict could be produced" (request-shape `422`, auth `401`/`403`, server `5xx`), carried as RFC 7807 `problem+json` and mapped to typed product errors.
48
49
 
49
50
  ### Standard artifacts on the validate report
@@ -104,10 +105,11 @@ Flat `src/` (mirrors `mthds-js`'s `runners/api` flatness — the SDK has one cli
104
105
  - `error-verdicts.ts` — `fallbackVerdict`, the table an `ApiResponseError` falls back to for a member the server did not send: the HTTP status, the platform `code`, and whether the body is named, which decides a `404`. Internal and pure. `pipelex-sdk` (Python) must apply the same table: `tests/fixtures/error-verdicts.json`, the case file this package's suite drives, is the contract, and the Python suite drives its own code through the identical copy `make shared-files` writes.
105
106
  - `run-may-have-started.ts` — the **pure** reading of whether a failed request that may create a run may still have started one: `answerMayHaveStartedRun(status, code)` for an answer and `transportMayHaveStartedRun(cause)` for a transport failure, every failure counting unless it proves otherwise (a failure of the connection's set-up, a `501`, the platform's `503` coded `pipeline_start_unavailable`, or any status that refuses the request). The client marks the requests that may create a run, `start` and the blocking `execute`, with a `RunCreation` flag it threads through `requestRaw`, `readObjectAnswer` and its error helpers into the constructors of `ApiUnreachableError` and `ApiResponseError`, which apply the reading and carry the answer as `runMayHaveStarted`, forcing `retryable` false when it is true; nothing changes an error after it is thrown. The Python twin is `pipelex_sdk/run_may_have_started.py`. See [errors.md](./errors.md#a-failed-run-start--runmayhavestarted).
106
107
  - `user-agent.ts` — client identification per the spec `conformance/specs/client-identification.md`, in the `conformance` repository beside the specs' tests: the exported `AppInfo` option, its RFC 9110 token validation (a `TypeError` on a bad field, a `RangeError` past the 512-character ceiling), its rendering, the runtime detection (Node, Bun, Deno, or a browser, where no header is set) and `buildUserAgent`, which the client calls once at construction. The barrel re-exports `buildUserAgent`, `validateAppInfo`, `MAX_USER_AGENT_LENGTH` and the `RuntimeInfo` type, so a consumer's raw fetches send the same value. The client's private `requestHeaders` is the one place API request headers are built, so every route carries the value; the artifact fetch of a presigned link never goes through it. See [client-identification.md](./client-identification.md).
108
+ - `exact-json.ts` — `parseExactJson` and `stringifyExactJson`, JSON whose integers stay exact, and `ExactJsonUnsupportedError`. The reader, which the client applies to every answer carrying a person's data (a method example, a run's record, a run's results, the blocking execute's answer), is one `JSON.parse` call whose reviver turns a number past `Number.MAX_SAFE_INTEGER` spelled as an integer into a `bigint` of its source text (`context.source`), so it reads everything else exactly as `JSON.parse` does, with no second parser to keep in step; a text holding no run of 16 digits is parsed with no reviver at all. On a runtime whose reviver gets no source text, it refuses a whole number past the safe range with `ExactJsonUnsupportedError`, which the client reports as an answer it cannot read, rather than rounding it. The writer, which `requestRaw` applies to every request body before the request is made, is one `JSON.stringify` call whose replacer turns each `bigint` into `JSON.rawJSON` text, so every getter and `toJSON` in the body runs once, and a `bigint` an inherited `toJSON` such as the `BigInt.prototype.toJSON` polyfill already turned into a string is looked up in its holder and written as its digits; a runtime without `JSON.rawJSON` refuses the `bigint`, as a `RequestArgumentError` from the client, rather than rounding it. The barrel exports all three, for a caller showing such data as JSON text; the error declares its verdict itself, `config` and not retryable, as `CodegenLockError` does. It imports nothing but the `ErrorDomain` type. See [exact-integers.md](./exact-integers.md).
107
109
  - `timers.ts` — `MAX_TIMER_DELAY_MS`, the longest delay `setTimeout` honours, and `isTimerDelay`, which every caller-supplied `timeoutMs` is checked against before it reaches a timer: a longer delay overflows and fires at once. It imports nothing, so the browser-safe upload entry uses it too.
108
110
  - `version.ts` — `SDK_VERSION`, in its own module so the client stamps it on the `User-Agent` without importing the barrel, which re-exports it.
109
111
  - `cli.ts` and `cli/` — the `pipelex-sdk` command, `run` and `script` ([`cli.md`](cli.md)): `cli.ts` is the executable `package.json` declares as the package's one `bin`, handing the process to `cli/main.ts`'s `runCommand`, and `cli/` holds the flags, the bundle reader, the inputs, the environment, the two subcommands and what they print. It sits at the TOP of the graph, the other way round from every other module: nothing imports it, the barrel does not export it, and it reaches the SDK only through `index.ts`, which `dependency-cruiser` enforces in both directions.
110
- - `index.ts` — the public barrel: `export * from "mthds/protocol"` (single import source for the standard surface) plus the client, models, run types, the standalone pure helpers (`runCodegenCheck`, `summarizeUsage`, `locateArtifacts`, `collectArtifacts`, `artifactFilename`), and errors.
112
+ - `index.ts` — the public barrel: `export * from "mthds/protocol"` (single import source for the standard surface) plus the client, models, run types, the standalone pure helpers (`runCodegenCheck`, `summarizeUsage`, `locateArtifacts`, `collectArtifacts`, `artifactFilename`, `parseExactJson`, `stringifyExactJson`), and errors.
111
113
 
112
114
  ## Client surface (current)
113
115
 
@@ -115,6 +117,7 @@ Flat `src/` (mirrors `mthds-js`'s `runners/api` flatness — the SDK has one cli
115
117
  - **Two independent opt-in lists on `validate`.** `render` asks the server to render a *view format* and adds a `rendered_<format>` field; `views` asks for a *structured view* and adds a same-named top-level field — today `input_form` and `output_form`, the per-pipe form descriptors. A caller that wants the forms without the dry-run verdict reads `pipeIo` instead, which derives them with no dry run. Each resolves its own tokens against its own supported set and unknown tokens are lenient-ignored on both, never a `422`. The client always asks for `render: ["markdown"]` but sends `views` only when a caller names a token, because an opt-in view exists precisely so the default response stays byte-identical for the consumers that discard it. `pipelex-api` gates `input_form` on the token as of 0.18.0; a 0.17.0 runner resolved no token and emitted the field on every valid verdict, which is why `PipelexValidationReport.input_form` is typed optional rather than required — the one typing that reads a response from either runner correctly.
116
118
  - **Method-bundle transport (pipelex-api extension):** `execute` / `start` / the blocking fallback accept the whole method — the `.mthds` plus its `funcs/*.py`, `structures/*.py`, `requirements.txt` — instead of only the inline `mthds_contents` text, so custom PipeFunc Python travels with the method. Two equivalent, mutually exclusive encodings: `files` (a `{ relativePath: text }` map) and `bundle_b64` (the same bundle as a base64 zip). A bundle is self-contained, so it satisfies the "something to run" precondition on its own — neither `pipe_code` nor `mthds_contents` is required beside it. See [run-sources](#run-sources) above.
117
119
  - **Method selectors on the run methods:** `execute` / `start` / `startAndWaitForResult` take the Pipelex API's `method_ref` (an address the runner resolves; provenance comes back typed as `method_provenance`) and the platform's `method_id` as **typed named options** (`PipelexRunOptions` / `PipelexStartOptions`), never `extra` entries. See [Pipelex API run extensions](#pipelex-api-run-extensions-method_ref) and [hosted run extensions](#hosted-run-extensions-method_id) above.
120
+ - **An idempotency key on a run start (hosted):** `start` and `startAndWaitForResult` take `idempotencyKey` (`PipelexStartRequestOptions`, intersected into `PipelexStartOptions`), sent as the `Idempotency-Key` header of `POST /v1/start` and never in the body; with no key there is no header. The hosted API binds the key to the run, answers a repeat of the same start with that run, and refuses the key with other options; a bare runner ignores the header. The client refuses a key that is not 1 to 255 visible ASCII characters with a `RequestArgumentError` before any request, the blocking `execute` fallback of `startAndWaitForResult` sends none, and the key leaves the error verdict as it is: a start that may have reached the server stays `runMayHaveStarted`, and the caller who sent a key recovers the run by sending the same start again under it. [errors.md](./errors.md#a-starts-idempotency-key--idempotencykey) holds the contract.
118
121
  - **Method selectors on `validate`:** the first argument is inline contents (`string[]`) or a `ValidateMethodSelector` — `{ method_ref }` (runner-resolved by address) or `{ method_id }` (hosted, platform-resolved) — under the strict tooling XOR: exactly one selector, no linkage exception, `mthds_sources` legal only beside inline contents. A selector-resolution failure is a non-2xx `ApiResponseError`, never an `is_valid: false` verdict.
119
122
  - **The files a bundle's steps read (`resources`, pipelex-api extension):** `validate` / `validateFiles` (in their last options argument), `execute` / `start` / `startAndWaitForResult` (both paths), the crate routes and `prepareInputs` (beside inline `files`) take `resources`, the files a `PipeDocGen` step's `template_file` names, keyed by the path the step names, each as its bytes (`Uint8Array`, `ArrayBuffer` or `Blob`), and send them as the wire's base64 map. `bundle-resources.ts` encodes them and refuses, before any request, a key the runner's path rule refuses and two keys for one file; the run routes and `validate` also mirror the runner's pairing refusals (beside a `method_ref`, or with no source on a run), while the crate routes leave theirs to the server, as they do the selector XOR. `resources` is reserved on `extra`, so it cannot bypass those checks. The valid verdict's `warnings` carry the template check's `template_check_warning` items, whose `template_file` and `template_location` `ValidationErrorItem` declares ahead of `mthds`, a difference the type-level pin states. See [bundle-resources.md](./bundle-resources.md).
120
123
  - **Crate routes (`/v1/resolve`, `/v1/codegen`, `/v1/pipe-io`):** `resolve` emits the **normalized library crate** (the MTHDS standard's Library Crate Format, fingerprint riding inside the payload); `codegen` projects that crate through two explicit axes — `kind` (`types`) × `target` (`ts-zod` / `python-pydantic` / `python-structures`) — into stamped artifacts plus their `codegen.lock`. All three share one closure envelope (`files: [{content, source?}]` XOR a `method_ref`, the address form server-resolved and the registry form a `501`) and return a **discriminated 200 verdict** (`is_valid`, with `CrateInvalidReport` as the shared invalid arm) rather than a bare payload, the same discipline as `validate`. They also take the hosted `method_id` (`PipelexHostedToolingExtensions`) as a third closure form under the strict three-way XOR — a pass-through the platform resolves, meaningless against a bare runner. Writing the artifacts and lock verbatim reproduces a local `pipelex codegen types` run byte-for-byte, so the offline `pipelex codegen check` passes — the SDK stays transport-only and does not write files. Verifying such a tree afterwards is `runCodegenCheck`, a standalone pure helper rather than a client method, because it needs no server at all. `pipeIo` derives a method's three I/O artifacts — the standard's `PipeIOContracts`, `InputForm` and `OutputForm`, imported from `mthds/protocol` — for the pipe the route selects (the request's qualified `pipe_ref`, else the method's own entry pipe) or for every pipe under `all_pipes`, with the runnability facts beside them and the closure's files echoed on `include_files`, and it runs no dry run; a selection it refuses is a `422` typed `EntryPipeNotFoundError` or `EntryPipeAmbiguousError`. See [crate-routes.md](./crate-routes.md).
@@ -129,6 +132,7 @@ The hosted catalog/account routes the webapp drives. All ride the same `{base}/v
129
132
 
130
133
  - **User profile:** `getMe` (`GET /v1/me`).
131
134
  - **Methods catalog:** `listMethods`, `getMethod`, `createMethod`, `writeDraft`, `renameMethod`, `publishMethod`, `listMethodVersions`, `getMethodVersion`, `deleteMethod`. **A saved method has a draft and immutable published versions.** Its content fields (`mthds`, `python`, `input_data`) are its draft, which `writeDraft` (`PUT /v1/methods/{id}/draft`) replaces without validating it; `updated_at` is the draft's token, which moves on every draft write and nothing else, and `draft_digest` the SHA-256 of its two file sets. A draft write may carry `expected_updated_at`, the token the caller last saw, and is then a compare-and-swap: a draft that moved since is a `409` `method_update_conflict` and nothing is written. `renameMethod` (`PATCH /v1/methods/{id}`) changes the name alone and moves no token. `publishMethod` (`POST /v1/methods/{id}/publish`) takes the required `expected_draft_updated_at` and answers a `MethodPublishResult` discriminated on `outcome` — `published` with the new version, `unchanged` with the existing latest version when the draft's digest equals it, `refused` with a `reason` (`invalid` or `not_runnable`), a `message` and the runner's `validation` verdict — every arm carrying the `method`; the SDK reads the nested method as `getMethod` does, and an answer whose `outcome` is none of these is an answer it cannot read. A publish that produced no verdict is thrown rather than answered: only a draft that differs from the latest version reaches the runner, and a runner that cannot be reached, answers unusably or does not finish within the platform's deadline is a `502` or `503` with nothing written, so a retry is safe, and a retry of a publish that landed while its answer was lost answers `unchanged` with the version it wrote. A method is stored as one item that keeps room for the summary a publish adds, so a draft that saves can always be published: a creation or a draft write is a `413` `payload_too_large` when it would grow the method past that room, below the store's item limit, and a rename is the same `413` for a name so long it would leave the method too large to publish. A version is numbered from 1, never reused, and holds the draft's files as they stood, its `source_digest`, its `crate_fingerprint` (`null` when the runner could not resolve the bundle in memory), the runner's version, and when and by whom it was published; `listMethodVersions` pages the summaries newest first (`MethodVersionPage`, `{items, nextCursor}`, a `limit` from 1 to 100, 20 by default, and a `422` outside that range), and `getMethodVersion` reads one with its sources, its `python` parsed as a method's is. A method read carries `latest_version` and `latest_published`, both `null` until the first publish, so the publish state is derived: never published, draft unchanged (`draft_digest === latest_published.source_digest`), or draft ahead. The method routes take a bare id and address the method itself, never one of its versions; the platform does not parse a suffix there, so `mt_x@3` would answer a `404` that reads as a method that does not exist, and each route refuses a suffixed id with `RequestArgumentError` before anything is sent, naming `parseMethodSelector` and `getMethodVersion`. The whole-method `updateMethod` is gone, replaced by the draft write and the rename. **`deleteMethod` is asynchronous and its return type says so:** `DELETE /v1/methods/{id}` answers `202` with a `MethodDeletionAccepted` (`method_id`, `deletion_state`, `deletion_job_id`) the moment the platform has claimed the method and terminated its in-flight workflows — the rest of the cascade (runs, events, S3 objects) is enqueued. A resolved promise means "accepted", never "gone"; completion is the row disappearing from `listMethods`, not any field of that body. The claim is a conditional write, so a double-clicked delete is a `409 method_being_deleted` rather than a second cascade over the same runs, and an unknown or foreign-org id is a `404`. The erasure deletes the method's versions with the rest. (This doc previously stated the SDK had no `delete` because the platform had no such route — the route has always existed; the claim was simply false.) `listMethods` returns **one page**, not the whole catalog — a `MethodPage` (`{items, nextCursor}`) served from a narrow index projection, so its cost is the page size rather than the size of the catalog. It used to return every method with its full `.mthds` bundle attached, which hit DynamoDB's 1 MB page cap at a couple hundred methods and came back truncated with no error and no flag, so methods silently vanished from the UI. Rows are therefore `MethodSummary`, **not** `MethodData`: no `mthds`, no `python`, no `updated_at`, because none of them is in the projection and putting `mthds` back is what restored the truncation. Reach for `getMethod(id)` when you need a method's source. `query.q` is applied server-side across the whole catalog, not over the page — filtering one page client-side would be searching 50 rows of 10,000 and calling it a search. `query.published` filters the same way, sent as `published=true` (the methods with a published version) or `published=false` (those never published), and combines with `q`. Each row carries the method's publish state, so a list tells its methods apart without reading each one: `latest_version` and `latest_published` (a `MethodVersionSummary`), both `null` when the method was never published, and `draft_digest`, which is `null` on a row that never stored one until its next draft write, unlike on `MethodData`, because the list reads an index that holds no bundle to digest; all three are optional, absent from a platform that does not serve them. Never published is `latest_version === null`, the draft unchanged is `draft_digest === latest_published.source_digest`, and the draft ahead is two digests that differ. Both filters run after the index read, so **a filtered page can come back empty and still carry a `nextCursor`**: an empty page is not the end of the list, and only a `null` cursor is. `iterateMethods` is the async iterator that follows the cursor for callers who genuinely want everything (`for await (const m of client.iterateMethods())`); it keeps going **past empty pages**, since `{items: [], nextCursor: "…"}` means "nothing matched in the slice I just read, keep going". A server that keeps minting fresh cursors forever stops it at a page ceiling far past any real catalog with a `PagingNotTerminatingError` carrying `pageLimit`, never a silently truncated stream; `iterateRuns` shares the same loop. It gives up only when the server stops advancing its cursor, and **throws** rather than returning a partial answer; like `iterateRuns` it is deliberately not a `listAllMethods(): Promise<MethodSummary[]>`, because an all-at-once helper needs a page cap and a cap means silently returning a truncated list. `MethodSummary.deletion_state` rides the list rows: a method mid-erasure stays listed so the UI can render it as "Deleting…", while `getMethod` refuses it with a 409. Full read responses (`MethodData`, from `getMethod`) carry `org_id`, `created_by_user_id`, a server-derived `description` (recomputed from the draft's top-level `description` on every draft write), the draft token and digest and the latest version's summary on top of the write contract's `name` / `mthds` / `input_data`. `getMethodClosure` is a client-side semantic layer over `getMethod` (not a route) that parses the draft's polymorphic `mthds` source into a runnable, provenance-labelled closure — the draft, not what a bare id runs — see [input-preparation.md](./input-preparation.md#getmethodclosure--the-explicit-expansion-utility).
135
+ - **Method examples:** `createMethodExample`, `listMethodExamples`, `iterateMethodExamples`, `getMethodExample`, `updateMethodExample`, `recordMethodExampleLatestRun`, `deleteMethodExample`, on `/v1/methods/{id}/examples`. An example is a named set of inputs saved on a method, shared across the organization, with an `input_revision` that rises each time its inputs change and the `latest_run_id` of those inputs, which an inputs edit clears. `recordMethodExampleLatestRun` records a run against the revision whose inputs it used and answers a `MethodExampleLatestRunResult` discriminated on `outcome`, `recorded` or `stale`, each arm carrying the `example`: a run that outlasted an edit is a verdict, never thrown, and an answer off the union is one the SDK cannot read; one helper, `readVerdict`, reads this verdict and `publishMethod`'s, the example checked once, by the reader every example goes through. Every answer carrying an example is read with `parseExactJson` and every request body written with `stringifyExactJson`, so an integer past `Number.MAX_SAFE_INTEGER` in the inputs reads as a `bigint` and goes back digit for digit, to an edit or as a run's inputs; `3.0` still reads as `3`, and inputs holding one sent back unchanged are an edit for the platform, which compares inputs as canonical JSON. Every example the client hands back, the page rows and the verdict's `example` included, is checked by `readMethodExample` against the fields the Python SDK's model requires, with the strict types it holds them to, an example breaking one being an answer the SDK cannot read. The list is paged oldest first by an opaque cursor, and a page may be short while `nextCursor` is set; `iterateMethodExamples` follows it through the loop `iterateMethods` and `iterateRuns` share, and refuses a method id at the call rather than at the first pull. Every method takes a bare catalog id, and the client refuses an example id that is empty, `.` or `..` or holds a lone surrogate, a create without its name or inputs or whose `run_id` is given but empty, an edit naming neither `name` nor `inputs`, and a latest-run write without a run id or a positive integer revision before sending. See [method-examples.md](./method-examples.md).
132
136
  - **Organizations:** `listMemberships`, `createOrganization`, `renameOrganization` (`PATCH`). The org "switch" is a WorkOS-session op (`/api/active-org`), not a `/v1` route — out of SDK scope.
133
137
  - **Billing:** `getSubscription`, `listPlans`, `listInvoices`, `createCheckout`, `changePlan` (409 `conflict` ⇒ no subscription), `getBillingPortal` (409 `conflict` ⇒ no subscription).
134
138
  - **Pipelex API keys (`plx_sk_…`):** `listPipelexApiKeys`, `createPipelexApiKey` (409 `pipelex_api_key_limit_reached`), `revokePipelexApiKey`, `rotatePipelexApiKey`. The plaintext `api_key` is returned once, on create/rotate.
package/docs/cli.md CHANGED
@@ -26,7 +26,7 @@ pipelex-sdk run --method <method> [--pipe <domain.pipe_code>] [--inputs <file> |
26
26
 
27
27
  The run goes through the SDK's `startAndWaitForResult`: on the hosted API a durable start, then polls until the run ends, however long it takes, and on a bare runner the blocking execute. Its `onStarted` callback prints `Run started: <id>` on stderr as soon as the run exists ([`run-results.md`](run-results.md)). The poll reads only the `main_stuff` artifact.
28
28
 
29
- **stdout carries the run's main output and nothing else**, as indented JSON (two spaces), followed by a newline: exactly what `JSON.stringify(value, null, 2)` prints, non-ASCII characters as they are. It is printed as the method produced it, unvalidated and unrepaired: a list output arrives either bare or wrapped as `{"items": […]}` depending on the runtime path, and is printed as it arrived. An output the method left absent, which the run delivers as the runtime's absence document (matched by its whole shape, as `cli-python` matches it) or as nothing, prints `null`, and stderr says `The method left its output "<name>" absent (<reason>), so the result is null.` A produced file is not downloaded: its short-lived signed URL is in the printed JSON. A reader that stops early and closes either stream, as `| head` or `2>&1 | head -1` does, ends nothing: the lines it no longer reads are dropped, and the command goes on waiting for the run it started and exits as it would have.
29
+ **stdout carries the run's main output and nothing else**, as indented JSON (two spaces), followed by a newline: exactly what `JSON.stringify(value, null, 2)` prints, non-ASCII characters as they are, except that an integer past `Number.MAX_SAFE_INTEGER`, which the client reads exactly, is printed with its exact digits, as the Python command prints it ([exact-integers.md](./exact-integers.md)). It is printed as the method produced it, unvalidated and unrepaired: a list output arrives either bare or wrapped as `{"items": […]}` depending on the runtime path, and is printed as it arrived. An output the method left absent, which the run delivers as the runtime's absence document (matched by its whole shape, as `cli-python` matches it) or as nothing, prints `null`, and stderr says `The method left its output "<name>" absent (<reason>), so the result is null.` A produced file is not downloaded: its short-lived signed URL is in the printed JSON. A reader that stops early and closes either stream, as `| head` or `2>&1 | head -1` does, ends nothing: the lines it no longer reads are dropped, and the command goes on waiting for the run it started and exits as it would have.
30
30
 
31
31
  ## `script`
32
32