@pipelex/sdk 0.29.1 → 0.30.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 +1 -2
- package/dist/client.d.ts +30 -90
- package/dist/client.js +29 -119
- package/dist/client.js.map +1 -1
- package/dist/errors.d.ts +5 -5
- package/dist/errors.js +5 -5
- package/dist/index.d.ts +1 -1
- package/dist/index.js.map +1 -1
- package/dist/models.d.ts +27 -152
- package/dist/models.js +2 -2
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/docs/architecture.md +7 -6
- package/docs/crate-routes.md +9 -5
- package/docs/errors.md +1 -1
- package/docs/input-preparation.md +5 -5
- package/package.json +2 -2
- package/docs/build-routes.md +0 -101
package/dist/index.d.ts
CHANGED
|
@@ -21,7 +21,7 @@ export type { GrantedUpload, UploadWithGrantOptions } from "./upload-grant.js";
|
|
|
21
21
|
export type { PrepareInputsBase, PrepareInputsClosure, PrepareInputsRequest, PreparedInputs, } from "./prepare-inputs.js";
|
|
22
22
|
export { locateArtifacts, collectArtifacts, artifactFilename, PIPELEX_STORAGE_SCHEME, BULK_RESOLVE_MAX_URIS, DEFAULT_ARTIFACT_MAX_BYTES, DEFAULT_ARTIFACT_TIMEOUT_MS, DEFAULT_DOWNLOAD_MAX_TOTAL_BYTES, DEFAULT_DOWNLOAD_CONCURRENCY, } from "./artifacts.js";
|
|
23
23
|
export type { ArtifactItemError, ArtifactLocation, ArtifactScope, BulkResolveStorageUrlsInput, BulkResolvedStorageUrls, DownloadArtifactsOptions, DownloadArtifactsRequest, DownloadArtifactsResult, DownloadedArtifact, FetchArtifactOptions, ResolvedArtifact, } from "./artifacts.js";
|
|
24
|
-
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,
|
|
24
|
+
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, } from "./models.js";
|
|
25
25
|
export { runCodegenCheck, isStampableArtifactPath, STAMPABLE_ARTIFACT_SUFFIXES, CodegenLockError, } from "./codegen-check.js";
|
|
26
26
|
export type { CodegenCheckInput, CodegenCheckReport, CodegenDrift, CodegenDriftCategory, CodegenTreeFile, } from "./codegen-check.js";
|
|
27
27
|
export type { UserProfile, ListMethodsQuery, MethodData, MethodDeletionAccepted, MethodDeletionState, MethodPage, MethodSummary, 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";
|
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,MAAM,aAAa,CAAC;AACrE,sFAAsF;AACtF,yFAAyF;AACzF,2EAA2E;AAC3E,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAazF,+FAA+F;AAC/F,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAE5D,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,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;
|
|
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,MAAM,aAAa,CAAC;AACrE,sFAAsF;AACtF,yFAAyF;AACzF,2EAA2E;AAC3E,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAazF,+FAA+F;AAC/F,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAE5D,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,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;AAoExB,+EAA+E;AAC/E,4EAA4E;AAC5E,iFAAiF;AACjF,0EAA0E;AAC1E,OAAO,EACL,eAAe,EACf,uBAAuB,EACvB,2BAA2B,EAC3B,gBAAgB,GACjB,MAAM,oBAAoB,CAAC;AAiD5B,wEAAwE;AACxE,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAa1F,oFAAoF;AACpF,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAS5C,+EAA+E;AAC/E,OAAO,EACL,gBAAgB,EAChB,mBAAmB,EACnB,yBAAyB,EACzB,qBAAqB,EACrB,2BAA2B,EAC3B,cAAc,EACd,eAAe,EACf,oBAAoB,EACpB,4BAA4B,EAC5B,qBAAqB,EACrB,sBAAsB,EACtB,uBAAuB,EACvB,kBAAkB,EAClB,gCAAgC,EAChC,yBAAyB,EACzB,oBAAoB,EACpB,sBAAsB,EACtB,2BAA2B,EAC3B,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,aAAa,CAAC"}
|
package/dist/models.d.ts
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* Holds the Dict-serialized protocol concretes (`DictStuff` / `DictWorkingMemory`
|
|
5
5
|
* / `DictPipeOutput` and the default `RunResultExecute` binding), the Pipelex
|
|
6
6
|
* `/v1/validate` surface (`PipelexValidationResult` + `ValidationErrorItem`), and
|
|
7
|
-
* the
|
|
8
|
-
* imported from the `mthds/protocol` subpath.
|
|
7
|
+
* the request/response models of the tools routes and the crate routes. Built on
|
|
8
|
+
* the protocol wire types imported from the `mthds/protocol` subpath.
|
|
9
9
|
*/
|
|
10
10
|
import type { InputForm, OutputForm, InvalidValidationReport, PipeIOContracts, RunResultExecute, RunResultStart, ValidationReport } from "mthds/protocol";
|
|
11
11
|
export interface DictStuff {
|
|
@@ -75,8 +75,7 @@ export interface PipelexRunResultStart extends RunResultStart {
|
|
|
75
75
|
* one of inline source / `method_ref` / `method_id` per request — any second
|
|
76
76
|
* selector is a request-shape `422`. An unknown or foreign-org id is a `404`
|
|
77
77
|
* (indistinguishable by design); a stored method with no MTHDS source is a
|
|
78
|
-
* `422`.
|
|
79
|
-
* no `method_id` (expand a stored method with `getMethodClosure` there).
|
|
78
|
+
* `422`.
|
|
80
79
|
*/
|
|
81
80
|
export interface PipelexHostedToolingExtensions {
|
|
82
81
|
/** A stored method's catalog id (`mt_…`) — hosted-only, resolved server-side. */
|
|
@@ -274,7 +273,7 @@ export type ValidationErrorCategory = "blueprint_validation" | "pipe_factory" |
|
|
|
274
273
|
* One structured bundle-validation error — mirror of pipelex's `ValidationErrorItem`.
|
|
275
274
|
* Carried by `PipelexInvalidReport.validation_errors[]` on the **200** invalid arm of
|
|
276
275
|
* `POST /v1/validate` (NOT a 422 — an invalid bundle is a produced verdict), by the
|
|
277
|
-
* VALID arm's advisory `warnings[]`, by the
|
|
276
|
+
* VALID arm's advisory `warnings[]`, by the crate routes' **200** invalid arm
|
|
278
277
|
* (`CrateInvalidReport.validation_errors[]`), by the 422 problem body a run route answers
|
|
279
278
|
* when the runner refuses the method for its validation errors
|
|
280
279
|
* (`ApiResponseError.validationErrors`), and by a failed run's stored report.
|
|
@@ -462,11 +461,8 @@ export interface FormatResponse {
|
|
|
462
461
|
changed: boolean;
|
|
463
462
|
diagnostics: Diagnostic[];
|
|
464
463
|
}
|
|
465
|
-
export type ConceptRepresentationFormat = "json" | "python" | "schema";
|
|
466
|
-
/** Encoding of a `/v1/build/inputs` template. Decides which field carries it back. */
|
|
467
|
-
export type InputsTemplateFormat = "json" | "toml";
|
|
468
464
|
/**
|
|
469
|
-
* One MTHDS file in a
|
|
465
|
+
* One MTHDS file in a crate closure. `source` is an optional provenance label (a
|
|
470
466
|
* filename, a URI) that the server threads onto every diagnostic it raises from
|
|
471
467
|
* this file, so an invalid verdict can point at the file that caused it.
|
|
472
468
|
*
|
|
@@ -481,11 +477,13 @@ export interface MthdsFileItem {
|
|
|
481
477
|
source?: string;
|
|
482
478
|
}
|
|
483
479
|
/**
|
|
484
|
-
* The closure selector every crate
|
|
485
|
-
* `/v1/pipe-io
|
|
480
|
+
* The closure selector every crate route shares — `/v1/resolve`, `/v1/codegen` and
|
|
481
|
+
* `/v1/pipe-io` (mirror of the server's `MthdsFilesRequest`).
|
|
486
482
|
*
|
|
487
483
|
* Supply the closure EITHER as inline `files` OR as a `method_ref` — never both, and
|
|
488
|
-
* never neither (both arms are a request-shape `422`)
|
|
484
|
+
* never neither (both arms are a request-shape `422`); the hosted `method_id` joins
|
|
485
|
+
* them as a third form on each route's own request (see
|
|
486
|
+
* {@link PipelexHostedToolingExtensions}). An **address-form** `method_ref`
|
|
489
487
|
* (`github.com/<owner>/<repo>[/<selector>][@<tag>]`) is resolved by the server
|
|
490
488
|
* (pipelex-api >= 0.21.0): the repository is fetched at the tag, the package is
|
|
491
489
|
* located by manifest identity, and its `.mthds` files feed the closure with their
|
|
@@ -494,162 +492,29 @@ export interface MthdsFileItem {
|
|
|
494
492
|
*
|
|
495
493
|
* The XOR is a server-side invariant, not a type-level one: expressing it as a union
|
|
496
494
|
* here would make the common `{ files }` call site pick a branch for no gain, and the
|
|
497
|
-
* server rejects the
|
|
495
|
+
* server rejects the illegal shapes with a typed `ApiResponseError` either way.
|
|
498
496
|
*/
|
|
499
497
|
export interface CrateRequestBase {
|
|
500
498
|
files?: MthdsFileItem[];
|
|
501
499
|
method_ref?: string;
|
|
502
500
|
}
|
|
503
501
|
/**
|
|
504
|
-
* The
|
|
505
|
-
* (mirror of the server's `
|
|
506
|
-
*/
|
|
507
|
-
export interface BuildRequestBase extends CrateRequestBase {
|
|
508
|
-
/**
|
|
509
|
-
* The pipe to project, as a QUALIFIED `domain.pipe_code` ref. Omit it to default
|
|
510
|
-
* to the closure's declared `main_pipe` — which fails (422) when the closure
|
|
511
|
-
* declares none, or declares several across its domains.
|
|
512
|
-
*/
|
|
513
|
-
pipe_ref?: string;
|
|
514
|
-
/**
|
|
515
|
-
* The `/v1/build/*` projections take NO `method_id` — the hosted platform's
|
|
516
|
-
* tooling selector covers `validate`/`resolve`/`codegen`/`pipe-io` only, and the build
|
|
517
|
-
* routes are deliberately excluded (they are frozen, being replaced by the
|
|
518
|
-
* codegen surface). Pinned to `never` so a stored-method caller reaches for
|
|
519
|
-
* `getMethodClosure` instead of a field no server resolves.
|
|
520
|
-
*/
|
|
521
|
-
method_id?: never;
|
|
522
|
-
}
|
|
523
|
-
export interface BuildInputsRequest extends BuildRequestBase {
|
|
524
|
-
/** `json` (default) puts the parsed template in `inputs`; `toml` puts raw text in `inputs_toml`. */
|
|
525
|
-
format?: InputsTemplateFormat;
|
|
526
|
-
/** Emit the ceremonial `{concept, content}` envelope per input. Defaults to the light shape. */
|
|
527
|
-
explicit?: boolean;
|
|
528
|
-
}
|
|
529
|
-
export interface BuildOutputRequest extends BuildRequestBase {
|
|
530
|
-
/** `schema` (default) and `json` put a parsed object in `output`; `python` puts source in `output_python`. */
|
|
531
|
-
format?: ConceptRepresentationFormat;
|
|
532
|
-
}
|
|
533
|
-
export interface BuildRunnerRequest extends BuildRequestBase {
|
|
534
|
-
/**
|
|
535
|
-
* Accept unresolved pipe signatures as pending rather than invalid. Alone among
|
|
536
|
-
* the build routes this one still runs the dry-run sweep, and the flag only ever
|
|
537
|
-
* parameterized that sweep.
|
|
538
|
-
*/
|
|
539
|
-
allow_signatures?: boolean;
|
|
540
|
-
}
|
|
541
|
-
export interface ConceptRequest {
|
|
542
|
-
spec: Record<string, unknown>;
|
|
543
|
-
}
|
|
544
|
-
export interface PipeSpecRequest {
|
|
545
|
-
pipe_type: string;
|
|
546
|
-
spec: Record<string, unknown>;
|
|
547
|
-
}
|
|
548
|
-
/**
|
|
549
|
-
* The `is_valid: false` arm shared by every crate-family route — `/v1/build/*`,
|
|
550
|
-
* `/v1/resolve`, `/v1/codegen`, and `/v1/pipe-io` (mirror of the server's one
|
|
551
|
-
* `CrateInvalidReport`).
|
|
502
|
+
* The `is_valid: false` arm shared by every crate route — `/v1/resolve`,
|
|
503
|
+
* `/v1/codegen` and `/v1/pipe-io` (mirror of the server's one `CrateInvalidReport`).
|
|
552
504
|
*
|
|
553
505
|
* They all follow `/validate`'s discipline: an unresolvable closure is the
|
|
554
506
|
* *successful product* of the call (the request was well-formed, the library was
|
|
555
507
|
* not), so it rides a **200** discriminated on `is_valid` — never a 4xx. Only a
|
|
556
508
|
* no-verdict condition throws `ApiResponseError`: a request the route cannot act on
|
|
557
|
-
* (
|
|
558
|
-
*
|
|
559
|
-
*
|
|
509
|
+
* (a pipe selection `pipe-io` refuses, an unknown `kind`/`target` on codegen), the
|
|
510
|
+
* reserved `method_ref`, auth, a server fault. Branch on `is_valid`, never on the
|
|
511
|
+
* transport.
|
|
560
512
|
*/
|
|
561
513
|
export interface CrateInvalidReport {
|
|
562
514
|
is_valid: false;
|
|
563
515
|
validation_errors: ValidationErrorItem[];
|
|
564
516
|
message: string;
|
|
565
517
|
}
|
|
566
|
-
/** Fields the valid arm of every `/v1/build/*` route carries. */
|
|
567
|
-
interface BuildValidReportBase {
|
|
568
|
-
is_valid: true;
|
|
569
|
-
/** The qualified pipe that was projected — the RESOLVED selector, always `domain.pipe_code`. */
|
|
570
|
-
pipe_ref: string;
|
|
571
|
-
/** The `pipe_ref` as submitted. Absent when it was omitted and defaulted to `main_pipe`. */
|
|
572
|
-
requested_pipe_ref?: string;
|
|
573
|
-
message: string;
|
|
574
|
-
}
|
|
575
|
-
/**
|
|
576
|
-
* The `/v1/build/inputs` valid arm. The template rides ONE of two fields, chosen by
|
|
577
|
-
* `format`: `inputs` (a parsed object) for `json`, `inputs_toml` (raw text) for
|
|
578
|
-
* `toml`. TOML cannot be carried as a parsed object without losing what makes it
|
|
579
|
-
* worth asking for — its concept comments and key order — so the two are separate
|
|
580
|
-
* fields and the unused one is absent from the body entirely.
|
|
581
|
-
*
|
|
582
|
-
* That "absent entirely" is why this is a union rather than one interface with two
|
|
583
|
-
* optional fields: `format` is a real discriminant, so narrowing on it hands you the
|
|
584
|
-
* field it selected as REQUIRED, with the other one statically unreachable.
|
|
585
|
-
*/
|
|
586
|
-
interface BuildInputsJsonReport extends BuildValidReportBase {
|
|
587
|
-
format: "json";
|
|
588
|
-
explicit: boolean;
|
|
589
|
-
inputs: Record<string, unknown>;
|
|
590
|
-
inputs_toml?: never;
|
|
591
|
-
}
|
|
592
|
-
interface BuildInputsTomlReport extends BuildValidReportBase {
|
|
593
|
-
format: "toml";
|
|
594
|
-
explicit: boolean;
|
|
595
|
-
inputs?: never;
|
|
596
|
-
inputs_toml: string;
|
|
597
|
-
}
|
|
598
|
-
export type BuildInputsValidReport = BuildInputsJsonReport | BuildInputsTomlReport;
|
|
599
|
-
export type BuildInputsResponse = BuildInputsValidReport | CrateInvalidReport;
|
|
600
|
-
/**
|
|
601
|
-
* The `/v1/build/output` valid arm. Same two-field split as the inputs template, for
|
|
602
|
-
* the same reason: `schema` and `json` are objects, `python` is source text — and so
|
|
603
|
-
* it is a discriminated union for the same reason too.
|
|
604
|
-
*/
|
|
605
|
-
interface BuildOutputObjectReport extends BuildValidReportBase {
|
|
606
|
-
format: "schema" | "json";
|
|
607
|
-
output: Record<string, unknown>;
|
|
608
|
-
output_python?: never;
|
|
609
|
-
}
|
|
610
|
-
interface BuildOutputPythonReport extends BuildValidReportBase {
|
|
611
|
-
format: "python";
|
|
612
|
-
output?: never;
|
|
613
|
-
output_python: string;
|
|
614
|
-
}
|
|
615
|
-
export type BuildOutputValidReport = BuildOutputObjectReport | BuildOutputPythonReport;
|
|
616
|
-
export type BuildOutputResponse = BuildOutputValidReport | CrateInvalidReport;
|
|
617
|
-
/**
|
|
618
|
-
* One stamped generated file — shared by `/v1/build/runner`'s structures projection
|
|
619
|
-
* and `/v1/codegen`'s artifact set. `path` is relative to the output root the client
|
|
620
|
-
* chooses; `content` is complete, stamp header included, and is written verbatim.
|
|
621
|
-
*/
|
|
622
|
-
export interface GeneratedArtifact {
|
|
623
|
-
path: string;
|
|
624
|
-
content: string;
|
|
625
|
-
}
|
|
626
|
-
/**
|
|
627
|
-
* The typed-structures projection the runner script imports from. Write `artifacts`
|
|
628
|
-
* and `lock` (as `lock_filename`) under `directory`, relative to the runner script,
|
|
629
|
-
* and the returned `python_code` runs against them.
|
|
630
|
-
*/
|
|
631
|
-
export interface RunnerStructures {
|
|
632
|
-
directory: string;
|
|
633
|
-
artifacts: GeneratedArtifact[];
|
|
634
|
-
lock: string;
|
|
635
|
-
lock_filename: string;
|
|
636
|
-
}
|
|
637
|
-
export interface BuildRunnerValidReport extends BuildValidReportBase {
|
|
638
|
-
python_code: string;
|
|
639
|
-
structures: RunnerStructures;
|
|
640
|
-
}
|
|
641
|
-
export type BuildRunnerResponse = BuildRunnerValidReport | CrateInvalidReport;
|
|
642
|
-
export interface ConceptResponse {
|
|
643
|
-
success: boolean;
|
|
644
|
-
concept_code: string;
|
|
645
|
-
toml: string;
|
|
646
|
-
}
|
|
647
|
-
export interface PipeSpecResponse {
|
|
648
|
-
success: boolean;
|
|
649
|
-
pipe_code: string;
|
|
650
|
-
pipe_type: string;
|
|
651
|
-
toml: string;
|
|
652
|
-
}
|
|
653
518
|
/**
|
|
654
519
|
* `POST /v1/resolve` request — the crate envelope (no projection axes) plus the
|
|
655
520
|
* hosted `method_id` selector. Exactly one of `files` / `method_ref` /
|
|
@@ -687,7 +552,8 @@ export type ResolveResponse = ResolveValidReport | CrateInvalidReport;
|
|
|
687
552
|
* projected into typed models) is the only kind served today; the future per-pipe kinds
|
|
688
553
|
* (`docs`, `tools`, `tests`) join it and select their pipe via `pipe_ref`. Input templates
|
|
689
554
|
* are deliberately NOT a kind here — they are user-editable scaffolds, never stamped or
|
|
690
|
-
* locked, and
|
|
555
|
+
* locked, and a client projects one from the input-form descriptor `/v1/pipe-io` returns
|
|
556
|
+
* (`renderInputsTemplate`, from `mthds/protocol`).
|
|
691
557
|
*/
|
|
692
558
|
export type CodegenKind = "types";
|
|
693
559
|
/**
|
|
@@ -712,6 +578,15 @@ export interface CodegenRequest extends CrateRequestBase, PipelexHostedToolingEx
|
|
|
712
578
|
*/
|
|
713
579
|
pipe_ref?: string;
|
|
714
580
|
}
|
|
581
|
+
/**
|
|
582
|
+
* One stamped generated file of `/v1/codegen`'s artifact set. `path` is relative to the
|
|
583
|
+
* output root the client chooses; `content` is complete, stamp header included, and is
|
|
584
|
+
* written verbatim.
|
|
585
|
+
*/
|
|
586
|
+
export interface GeneratedArtifact {
|
|
587
|
+
path: string;
|
|
588
|
+
content: string;
|
|
589
|
+
}
|
|
715
590
|
/**
|
|
716
591
|
* The `/v1/codegen` valid arm — the stamped artifact set plus its lock.
|
|
717
592
|
*
|
package/dist/models.js
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* Holds the Dict-serialized protocol concretes (`DictStuff` / `DictWorkingMemory`
|
|
5
5
|
* / `DictPipeOutput` and the default `RunResultExecute` binding), the Pipelex
|
|
6
6
|
* `/v1/validate` surface (`PipelexValidationResult` + `ValidationErrorItem`), and
|
|
7
|
-
* the
|
|
8
|
-
* imported from the `mthds/protocol` subpath.
|
|
7
|
+
* the request/response models of the tools routes and the crate routes. Built on
|
|
8
|
+
* the protocol wire types imported from the `mthds/protocol` subpath.
|
|
9
9
|
*/
|
|
10
10
|
export {};
|
|
11
11
|
//# sourceMappingURL=models.js.map
|
package/dist/version.d.ts
CHANGED
package/dist/version.js
CHANGED
package/docs/architecture.md
CHANGED
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
- read the model deck and version handshake (`models` / `version`),
|
|
10
10
|
- and reach the Pipelex product surface (user profile, methods catalog, organizations, billing, API keys, onboarding, storage).
|
|
11
11
|
|
|
12
|
+
`models` returns the deck as the runner sent it, with no runtime check, and types each entry's `type` as `ModelCategory | (string & {}) | null`: a category `mthds` defines, `judgment` among them, or the raw value of one this version does not define, which the MTHDS Protocol requires a client reading a model list to keep rather than fail on.
|
|
13
|
+
|
|
12
14
|
## Dependency direction (one-way)
|
|
13
15
|
|
|
14
16
|
```
|
|
@@ -23,7 +25,7 @@
|
|
|
23
25
|
## Brand boundary
|
|
24
26
|
|
|
25
27
|
- **MTHDS-branded (lives in `mthds`):** protocol wire models, the standard `ValidationReport` / `ValidationResult` shapes, `.mthds` utilities, the `MthdsProtocolClient`.
|
|
26
|
-
- **Pipelex-branded (lives here):** `PipelexApiClient`, run store / durable lifecycle,
|
|
28
|
+
- **Pipelex-branded (lives here):** `PipelexApiClient`, run store / durable lifecycle, the crate and tools routes, `PipelexValidationResult`, hosted-product typed errors, API keys / orgs / billing / methods catalog / storage / onboarding.
|
|
27
29
|
- Inside a Pipelex envelope, field names stay neutral (`bundle_blueprint`, `pipe_io_contracts`, `input_form`, `liftable_pipes`, `graph_spec`) — Pipelex branding is reserved for genuinely runtime-specific envelopes.
|
|
28
30
|
|
|
29
31
|
## Module format & packaging
|
|
@@ -72,7 +74,7 @@ A run request carries its method inline exactly one of three ways: `mthds_conten
|
|
|
72
74
|
|
|
73
75
|
- **It is a named option, not an `extra` entry.** Typing its own platform's arguments is the one job a layer-3 client exists to do; `extra` stays the escape hatch for extensions this client does not know about (a third-party server, or a newer version of ours). That split, and the reserved-keys guard that enforces it, are normative for every client in the layered stack: a client types the arguments of the platform it is built for, and only the layer that owns an argument may validate or reject it. It was previously passed as `extra: { method_id }`, which worked but documented nothing and validated nothing.
|
|
74
76
|
- **The guard is per layer.** `method_id` is reserved on `extra` _here_ and must never become reserved in `mthds` / `mthds-python`: a protocol client talking to another vendor's server has no business rejecting that vendor's arguments.
|
|
75
|
-
- **Pure pass-through — nothing is expanded client-side.** The platform resolves the id against the org's catalog. The same posture holds across the tooling routes: `validate` / `resolve` / `codegen` / `pipeIo` take a typed `method_id` the platform resolves server-side (see the surface list below), and so does `prepareInputs`, which composes a `pipeIo` of its own.
|
|
77
|
+
- **Pure pass-through — nothing is expanded client-side.** The platform resolves the id against the org's catalog. The same posture holds across the tooling routes: `validate` / `resolve` / `codegen` / `pipeIo` take a typed `method_id` the platform resolves server-side (see the surface list below), and so does `prepareInputs`, which composes a `pipeIo` of its own. `getMethodClosure` stays public as the local expansion utility, for a caller that wants a stored method's files in hand or talks to a bare runner, which has no catalog to resolve an id against.
|
|
76
78
|
- **Alone it is a run source; alongside an inline source it is linkage.** With no inline source the platform resolves and runs the stored method. With one, the inline source is what RUNS (precedence) and the id is recorded as run-history linkage on the Run row — the index key `GET /v1/runs?method_id=` queries. Rejecting the combination is not an option: it once orphaned every unsaved-bundle run from its method. The client therefore counts `method_id` towards its "something to run" precondition, and never treats it as an exclusivity violation.
|
|
77
79
|
- **It rides the blocking fallback too.** `startAndWaitForResult` degrades to `POST /v1/execute` against a runner with no run store, and the selector goes with it — so a bare `pipelex-api` answers a `422` that names the key (its Rule 4 diagnosis: "a hosted-only selector must be sent to the hosted API") instead of the client silently dropping it and running something else.
|
|
78
80
|
- **An empty string is treated as absent.** `method_id: ""` selects no method and links nothing, so it is not sent and does not satisfy the precondition.
|
|
@@ -82,7 +84,7 @@ A run request carries its method inline exactly one of three ways: `mthds_conten
|
|
|
82
84
|
Flat `src/` (mirrors `mthds-js`'s `runners/api` flatness — the SDK has one client, so no runner/registry abstraction):
|
|
83
85
|
|
|
84
86
|
- `client.ts` — `PipelexApiClient`: the `request()` pipeline (auth, base URL, timeouts/abort, problem-details parsing) and every route. `implements MTHDSProtocol<DictPipeOutput>` so the protocol-execution methods stay shaped like the standard.
|
|
85
|
-
- `models.ts` — Dict-serialized concretes (`DictStuff` / `DictWorkingMemory` / `DictPipeOutput` / `DictRunResultExecute`), the `/v1/validate` surface (`PipelexValidationResult`, `ValidationErrorItem`, and the `SuggestedFix` / `FixOp` repair vocabulary its items carry — the standard's declarations, restated because `mthds` exports them only from its package root and pinned to it by a type-level test, see [errors.md](./errors.md#a-validation-item--validationerroritem)), the tools surface (`Diagnostic` / `LintResponse` / `FormatResponse`), and the crate-
|
|
87
|
+
- `models.ts` — Dict-serialized concretes (`DictStuff` / `DictWorkingMemory` / `DictPipeOutput` / `DictRunResultExecute`), the `/v1/validate` surface (`PipelexValidationResult`, `ValidationErrorItem`, and the `SuggestedFix` / `FixOp` repair vocabulary its items carry — the standard's declarations, restated because `mthds` exports them only from its package root and pinned to it by a type-level test, see [errors.md](./errors.md#a-validation-item--validationerroritem)), the tools surface (`Diagnostic` / `LintResponse` / `FormatResponse`), and the crate-route request/response models — the shared `MthdsFileItem` / `CrateRequestBase` / `CrateInvalidReport` vocabulary plus the `/v1/resolve`, `/v1/codegen` and `/v1/pipe-io` shapes built on it, `GeneratedArtifact` among them.
|
|
86
88
|
- `product-models.ts` — the snake_case wire shapes for the hosted-product management routes (profile, methods catalog, organizations, billing, API keys, onboarding, storage, runs list/detail/update). Each interface models only the fields the product actually consumes — no speculative mirrors.
|
|
87
89
|
- `error-models.ts` — the error-report wire models: `RunErrorReport`, the runner's `ErrorReport` typed with every field it carries (with `UserAction`, `ProviderErrorMetadata` and `MigrationErrorBlock`), which is the one type for a failed run's report on `RunPublic.error`, `PipelineRun.error`, `RunHistoryItem.error`, the failed arm of `RunResultState` and `RunFailedError.error`; and `ProblemDetails` / `FieldError`, the typed members of a problem document that `ApiResponseError` exposes. Every field is optional and every interface keeps an index signature, because the runner owns the shape and adds fields without asking. Types only: it imports the `ValidationErrorItem` type and nothing else. See [errors.md](./errors.md).
|
|
88
90
|
- `method-source.ts` — `methodSourceToContents`, the canonical parser turning a stored method's polymorphic `mthds` source (raw single-bundle text XOR a JSON `{name, content}[]` file array) into a flat list of file contents. A verbatim port of the platform's `method_source_to_contents` so the SDK and runtime read a stored source identically; exported from the barrel and consumed by `getMethodClosure`. See [input-preparation.md](./input-preparation.md#getmethodclosure--the-explicit-expansion-utility).
|
|
@@ -105,8 +107,7 @@ Flat `src/` (mirrors `mthds-js`'s `runners/api` flatness — the SDK has one cli
|
|
|
105
107
|
- **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.
|
|
106
108
|
- **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.
|
|
107
109
|
- **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.
|
|
108
|
-
- **
|
|
109
|
-
- **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`. They share the build routes' closure envelope and its **discriminated 200 verdict** (`CrateInvalidReport` is literally the same invalid arm), and additionally 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).
|
|
110
|
+
- **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).
|
|
110
111
|
- **Tools (`/v1/lint`, `/v1/format`):** `lint`, `format` — single-file static diagnostics and canonical formatting, served by any pipelex-api runner (no inference, no bundle load). Both are **diagnostic endpoints** like `validate`: a malformed `.mthds` file is a produced verdict on a **200** carrying `diagnostics[]`, never a thrown error — `format` additionally echoes the content back unchanged with `changed: false`. Only a no-verdict condition is non-2xx: a malformed body, **malformed formatter `options`** (e.g. a non-numeric `column_width` ⇒ 422), auth, or a server fault, all mapped to the typed `ApiResponseError`. `lint` is the cheap static check (syntax / schema / semantic); it does not replace `validate`, which loads the bundle, resolves across files, and dry-runs the pipes.
|
|
111
112
|
- **Durable run lifecycle (hosted extension — NOT protocol):** `getRunStatus`, `getRunResult` (with an optional `artifacts` selection sent as `?artifacts=`, see [run-results.md](./run-results.md#reading-only-some-artifacts--artifacts)), `waitForResult`, `startAndWaitForResult` (handshakes `/v1/version`, takes the durable start+poll path on a hosted deployment, and self-heals to the blocking `execute` against a bare runner). A run that ended without completing answers the results read with a `409` whose `run_status` and `error` members carry its status and its stored error report; `getRunResult` turns it into the `failed` arm (`status`, `message` from `detail`, `error`) and the waiting calls on the durable path into a `RunFailedError` carrying the same (the blocking fallback's failure is the runner's `ApiResponseError`), the status read from the member, or from the `detail` sentence on a platform that does not send it yet. The status read serves the same report as `RunRead.error`. See [errors.md](./errors.md#a-failed-run--runerrorreport). Reading what a completed run consumed is `summarizeUsage(results)`, a standalone pure helper rather than a client method, because it folds the usage pair the results already carry and needs no server. See [run-usage.md](./run-usage.md#summarizing-a-run--summarizeusage).
|
|
112
113
|
- **Health:** `health` (origin-level `/health`).
|
|
@@ -133,4 +134,4 @@ The hosted catalog/account routes the webapp drives. All ride the same `{base}/v
|
|
|
133
134
|
Two layers, split by whether a server is in the loop:
|
|
134
135
|
|
|
135
136
|
- **Unit suites (`tests/*.test.ts`, `make test`):** mock the fetch boundary (`vi.spyOn(globalThis, "fetch")`) and pin the client's wire behavior — URLs, request bodies, status→error mapping, poll semantics. These run everywhere, including CI. The codegen-check suite is the exception that proves the rule: it has no server to mock, so it runs against **vendored real codegen output** under `tests/fixtures/codegen/` — artifacts and lock emitted by an actual `pipelex codegen types` run, committed beside the `.mthds` they came from. A hand-written stamp would only prove the port agrees with itself. The artifacts are vendored with a trailing `.txt` and their real names restored at load time, because `format:check`, `lint`, and `typecheck:test` all glob `tests/**/*.ts` — and a single reformatted byte would invalidate the very hash the fixture exists to pin.
|
|
136
|
-
- **E2E suites (`tests/e2e/*.e2e.ts`, `make test-e2e`):** no mocks — they drive a **live pipelex-api server** (`PIPELEX_E2E_BASE_URL`, default `http://localhost:8081`) and verify the diagnostic-endpoint contract end-to-end with correct and malformed MTHDS bundles: clean content lints with zero diagnostics and formats to itself (idempotently), malformed content comes back as a 200 verdict (`diagnostics[]` on lint; `diagnostics[]` plus the content echoed back unchanged with `changed: false` on format; `is_valid: false` + `validation_errors[]` on validate), and malformed formatter options surface as a 422 `ApiResponseError`. The crate suite adds the case only a live server can settle: the `kind` / `target` vocabulary is a mirror of a Python `StrEnum` in another repo, so nothing but a real call proves the two still agree — and it cross-checks that `codegen`'s `crate_fingerprint` equals the `fingerprint` `resolve` returns for the same closure. It then runs `runCodegenCheck` over the artifacts and lock the server just emitted — verbatim first (current, with the lock header's fingerprint matching the response's), then mutated in memory once per drift category, for a `.ts` target and a `.py` one. The unit suite pins the port against vendored bytes; only this pins it against the stamp and lock bytes the server writes **today**, which is the pairing that matters when a consumer commits the server's artifacts and gates CI on the SDK's verdict about them. The same suite drives `pipeIo` across all three selectors: the artifacts under the resolved ref, their equality with `validate`'s views for the same closure, the `include_files` echo, `all_pipes` on a method with no entry pipe, a `method_ref` package's manifest entry pipe, the invalid arm, and the typed selection `422`. Its `method_id` case, like the `prepareInputs` suite's, runs only when `PIPELEX_E2E_METHOD_ID` names a stored method the key's organization owns, since only a hosted origin can resolve one, and is skipped otherwise. The distinct `.e2e.ts` suffix + `vitest.e2e.config.ts` keep them out of the default `vitest run`, so `make test` / CI never require a server. An unreachable server is an error, never a silent skip, and it is reported once: `make test-e2e` preflights the target with a single `curl` and bails with a one-line message, instead of letting
|
|
137
|
+
- **E2E suites (`tests/e2e/*.e2e.ts`, `make test-e2e`):** no mocks — they drive a **live pipelex-api server** (`PIPELEX_E2E_BASE_URL`, default `http://localhost:8081`) and verify the diagnostic-endpoint contract end-to-end with correct and malformed MTHDS bundles: clean content lints with zero diagnostics and formats to itself (idempotently), malformed content comes back as a 200 verdict (`diagnostics[]` on lint; `diagnostics[]` plus the content echoed back unchanged with `changed: false` on format; `is_valid: false` + `validation_errors[]` on validate), and malformed formatter options surface as a 422 `ApiResponseError`. The crate suite adds the case only a live server can settle: the `kind` / `target` vocabulary is a mirror of a Python `StrEnum` in another repo, so nothing but a real call proves the two still agree — and it cross-checks that `codegen`'s `crate_fingerprint` equals the `fingerprint` `resolve` returns for the same closure. It then runs `runCodegenCheck` over the artifacts and lock the server just emitted — verbatim first (current, with the lock header's fingerprint matching the response's), then mutated in memory once per drift category, for a `.ts` target and a `.py` one. The unit suite pins the port against vendored bytes; only this pins it against the stamp and lock bytes the server writes **today**, which is the pairing that matters when a consumer commits the server's artifacts and gates CI on the SDK's verdict about them. The same suite drives `pipeIo` across all three selectors: the artifacts under the resolved ref, their equality with `validate`'s views for the same closure, the `include_files` echo, `all_pipes` on a method with no entry pipe, a `method_ref` package's manifest entry pipe, the invalid arm, and the typed selection `422`. Its `method_id` case, like the `prepareInputs` suite's, runs only when `PIPELEX_E2E_METHOD_ID` names a stored method the key's organization owns, since only a hosted origin can resolve one, and is skipped otherwise. The distinct `.e2e.ts` suffix + `vitest.e2e.config.ts` keep them out of the default `vitest run`, so `make test` / CI never require a server. An unreachable server is an error, never a silent skip, and it is reported once: `make test-e2e` preflights the target with a single `curl` and bails with a one-line message, instead of letting every suite fail in `beforeAll` and print a socket-error dump each. The per-suite `beforeAll` guard stays as the backstop for a direct `npm run test:e2e` run. Both probe **`/v1/version`**, deliberately: a bare runner serves the origin-level `/health` and a hosted origin does not (it answers `/v1/health` instead), so `/v1/version` is the one unauthenticated route both answer — probing anything else reports a perfectly reachable hosted origin as down. The target itself is resolved once, in the Makefile, and exported along with `PIPELEX_API_KEY`, so the URL the preflight checks is always the URL the suites call: the shell environment (or a `make test-e2e PIPELEX_E2E_BASE_URL=...` override) wins, then `.env`, then `http://localhost:8081`. The run echoes the resolved target before it starts, since `.env` can now supply it invisibly. Note that a hosted origin cannot run the whole suite today — `lint` and `format` are not exposed there (gateway `403`), while the protocol routes and the `resolve` and `codegen` crate routes answer, and `pipe-io` answers only once the platform's proxy and the gateway list it — so a fully green run means a local runner. The upload-grant suite needs the same hosted platform: it requests a grant, sends a small PDF with `uploadWithGrant`, reads the bytes back equal through `fetchArtifact`, and proves the refusals the error mapping reads — the `412` of a used grant, the `403 SignatureDoesNotMatch` of a file one byte longer than declared, and the `413` of a declared size over the cap. It runs in Node, whose `fetch` sends no CORS preflight, so the bucket's CORS rule is proven by a page, not by it. The artifact suite is the mirror image: it uploads a file with `prepareInputs`, runs a pass-through and brings the file back down with `downloadArtifacts` over `working_memory`, bytes equal, so it needs a hosted platform carrying `POST /v1/pipe-io` (which `prepareInputs` reads), the upload, run-lifecycle and bulk resolve routes, and a key for it, and it fails honestly rather than skipping against a bare runner.
|
package/docs/crate-routes.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Crate routes (`/v1/resolve`, `/v1/codegen`, `/v1/pipe-io`)
|
|
2
2
|
|
|
3
|
-
Three routes project a **closure** of MTHDS files into the artifacts downstream tooling actually consumes: `resolve` emits the **normalized library crate**, `codegen` projects that crate into **stamped typed artifacts** plus their lock, and `pipeIo` derives a method's **pipe I/O contracts, input form and output form** without a dry run.
|
|
3
|
+
Three routes project a **closure** of MTHDS files into the artifacts downstream tooling actually consumes: `resolve` emits the **normalized library crate**, `codegen` projects that crate into **stamped typed artifacts** plus their lock, and `pipeIo` derives a method's **pipe I/O contracts, input form and output form** without a dry run. They are Pipelex API extensions rather than MTHDS Protocol operations — but note the ownership split: the _crate_ and the three I/O artifacts are standard-owned (the MTHDS Library Crate Format, and the standard's pipe I/O contracts and form descriptors), while the HTTP surface serving them, and every type projection on top of the crate, are ours.
|
|
4
4
|
|
|
5
5
|
> **`resolve` and `codegen` are served on every hosted origin, and by any `pipelex-api` runner.** On the hosted plane a route is reachable only when the gateway's API-key allowlist and the platform's tooling proxy both list its path — each enumerates routes explicitly, and an unlisted path answers a gateway `403 {"message":"Forbidden"}`, refused before any service sees the request, so not even an RFC 7807 problem body. `resolve` and `codegen` are listed by both.
|
|
6
6
|
>
|
|
@@ -25,7 +25,11 @@ interface PipelexHostedToolingExtensions {
|
|
|
25
25
|
}
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
`source` is why the envelope carries files rather than bare strings. A closure is a set of files, and a diagnostic that cannot say _which_ file it came from is much harder to act on. Pass a filename (or any label) per file and, **when the engine can attribute the diagnostic to a file**, it comes back as `source` on the corresponding `validation_errors[]` item.
|
|
29
|
+
|
|
30
|
+
Treat that attribution as best-effort, not a guarantee — which is why `ValidationErrorItem.source` is typed optional and why the `resolve` sample below reads `err.source ?? "?"`. Some arms don't populate it: graph-level `dry_run` and `pipe_factory` items have no single owning file, and a `main_pipe` naming a nonexistent pipe currently reports its provenance in the message prose while leaving the structured field unset. The syntax-error arm, the common case, does thread it.
|
|
31
|
+
|
|
32
|
+
> `MthdsFileItem` is not the same type as `MthdsFile` (the one `validateFiles()` takes). `/v1/validate` spells the provenance label `uri` and carries it in a parallel `mthds_sources` array; this envelope spells it `source` and carries it inline. The two collapse into one only if `/v1/validate` ever migrates onto `files[]` — a protocol-level change owned by the MTHDS standard, not ours to make here.
|
|
29
33
|
|
|
30
34
|
An **address-form** `method_ref` (`github.com/<owner>/<repo>[/<selector>][@<tag>]`) is resolved by the server through the same fetch path as a `method_ref` run: the repository fetched at the tag, the package located by manifest identity, the package's real relative paths feeding the per-file `source` labels. Any non-address reference stays reserved and answers `501`.
|
|
31
35
|
|
|
@@ -33,7 +37,7 @@ An **address-form** `method_ref` (`github.com/<owner>/<repo>[/<selector>][@<tag>
|
|
|
33
37
|
|
|
34
38
|
Supplying **no** selector or **more than one** is a request-shape `422` — the tooling routes are stateless, so there is no linkage exception; a second selector could only be ignored, which is the worst contract of the three. The SDK does not model the XOR in the type system — the union would force the overwhelmingly common `{ files }` call site to pick a branch for no gain, and the server's answer is a typed `ApiResponseError` either way.
|
|
35
39
|
|
|
36
|
-
The old advice to expand a stored method client-side (`resolve({ files: await client.getMethodClosure(methodId) })`) remains valid — `getMethodClosure` stays public as the local expansion utility, and it is what a caller uses against a bare runner
|
|
40
|
+
The old advice to expand a stored method client-side (`resolve({ files: await client.getMethodClosure(methodId) })`) remains valid — `getMethodClosure` stays public as the local expansion utility, and it is what a caller uses against a bare runner, which has no catalog to resolve an id against.
|
|
37
41
|
|
|
38
42
|
A `method_ref` makes the server fetch the repository before it answers, so the client gives a call carrying one a fetch-sized budget (three minutes) instead of the 30-second default. On the hosted API the gateway caps every request at about 30 seconds whatever the client allows, so a cold `method_ref` clone can answer a `502`; retrying clears it once the runner has cached the clone.
|
|
39
43
|
|
|
@@ -120,7 +124,7 @@ The valid arm (`PipeIOValidReport`):
|
|
|
120
124
|
|
|
121
125
|
## The response is a verdict, not a payload
|
|
122
126
|
|
|
123
|
-
All three routes return a **discriminated 200**, the same discipline as `validate
|
|
127
|
+
All three routes return a **discriminated 200**, the same discipline as `validate`: an unresolvable closure is the _successful product_ of the call (the request was well-formed; the library was not), so it rides a 200 with `is_valid: false` and the shared `CrateInvalidReport`, carrying the same structured `validation_errors[]` as `validate`'s invalid arm.
|
|
124
128
|
|
|
125
129
|
**Branch on `is_valid` before reading the arm.** A consumer that only catches throws will render a success over an unusable result, because nothing threw.
|
|
126
130
|
|
|
@@ -138,7 +142,7 @@ Only a **no-verdict** condition, as the typed `ApiResponseError` — branch on i
|
|
|
138
142
|
| `502` | On a hosted origin, a cold `method_ref` clone that outran the gateway's 30-second cap; a retry clears it. |
|
|
139
143
|
| `5xx` | Server fault, including on `pipeIo` a pipe whose artifacts cannot be derived. |
|
|
140
144
|
|
|
141
|
-
Note the split
|
|
145
|
+
Note the split: a bad **closure** is a 200 verdict; a bad **request** throws.
|
|
142
146
|
|
|
143
147
|
(The offline check below is not a route and throws its own `CodegenLockError` instead — it never reaches the network.)
|
|
144
148
|
|
package/docs/errors.md
CHANGED
|
@@ -114,7 +114,7 @@ The members `mthds`'s own `ApiResponseError` carries (`type`, `title`, `instance
|
|
|
114
114
|
|
|
115
115
|
## A validation item — `ValidationErrorItem`
|
|
116
116
|
|
|
117
|
-
A method refused for what it says, rather than for how its run went, comes back as a list of validation items. They ride the `/v1/validate` verdict (its invalid arm's `validation_errors[]`, and the advisory `warnings[]` of its valid arm) and the
|
|
117
|
+
A method refused for what it says, rather than for how its run went, comes back as a list of validation items. They ride the `/v1/validate` verdict (its invalid arm's `validation_errors[]`, and the advisory `warnings[]` of its valid arm) and the crate routes' invalid verdict (`CrateInvalidReport.validation_errors[]`), each a `200` because an invalid bundle is a produced verdict; the `422` a run route answers when the runner refuses the method for its validation errors, as `ApiResponseError.validationErrors`; and a failed run's report, as `validation_errors`. Each item has a `category` and a `message`; the other members locate the error and say what to do next, and each is present only when the runner knows it:
|
|
118
118
|
|
|
119
119
|
| Member | Meaning |
|
|
120
120
|
|---|---|
|
|
@@ -147,13 +147,13 @@ client.getMethodClosure(methodId) → MthdsFileItem[]
|
|
|
147
147
|
|
|
148
148
|
`getMethodClosure` is the public **local expansion utility** — a client-side semantic layer over `getMethod` (the platform has no route that returns a parsed closure). It fetches the method, parses its polymorphic `mthds` source with [`methodSourceToContents`](#methodsourcetocontents--the-canonical-source-parser), and labels each resulting file with the `method_id` as its `source` provenance.
|
|
149
149
|
|
|
150
|
-
Reach for it whenever you want the files **in hand** — to edit, to diff, or to
|
|
150
|
+
Reach for it whenever you want the files **in hand** — to edit, to diff, or to send to a bare runner, which has no catalog to resolve an id against:
|
|
151
151
|
|
|
152
152
|
```
|
|
153
|
-
|
|
153
|
+
runner.resolve({ files: await hosted.getMethodClosure("mt_…") })
|
|
154
154
|
```
|
|
155
155
|
|
|
156
|
-
|
|
156
|
+
Every method-taking operation — `execute` / `start`, `validate` / `resolve` / `codegen` / `pipeIo`, and `prepareInputs` — takes a `method_id` **natively** on the hosted API, as a server pass-through: the platform resolves it and injects the stored source before the runner sees the request (see [architecture.md → hosted run extensions](./architecture.md#hosted-run-extensions-method_id)). That is the uniform rule — *an id option is always a server pass-through, and any client-side expansion is the caller's own explicit call*.
|
|
157
157
|
|
|
158
158
|
- **Requires an API key.** The methods catalog is org-scoped to the key's org, so resolution only works with an authenticated Pipelex-product key.
|
|
159
159
|
- **Unknown or foreign-org id → the `getMethod` `404`** (`ApiResponseError`, `code: "not_found"`), propagated unchanged. An id from another org is indistinguishable from a nonexistent one — both 404.
|
|
@@ -172,7 +172,7 @@ A stored method's `mthds` field is **polymorphic**: it is either the raw single-
|
|
|
172
172
|
Each input may be submitted in **either** of two shapes, and preparation treats them equivalently:
|
|
173
173
|
|
|
174
174
|
- **Compact** — the bare value: a source string / bytes / canonical `{ url }` content (e.g. `photo: "https://…/p.png"`).
|
|
175
|
-
- **Explicit envelope** — the `{ concept, content }` shape
|
|
175
|
+
- **Explicit envelope** — the `{ concept, content }` shape an explicit inputs template carries per input (`renderInputsTemplate(descriptor, { explicit: true, format })`, from `mthds/protocol` and re-exported here) (e.g. `photo: { concept: "native.Image", content: { url: "https://…/p.png" } }`). This is the default template the hosted console and MCP hand agents to fill, so an agent that fills the template can hand it straight back.
|
|
176
176
|
|
|
177
177
|
When a value is an envelope (a plain object whose keys are **exactly** `concept` and `content` — matching the runtime's `_is_explicit` in `input_shaper.py`), preparation unwraps `content`, interprets it exactly as the compact value would be, and **re-wraps** the result — so the concept annotation rides through to the run. The runtime accepts the envelope as a run input (`input_shaper.py` `_is_explicit` / `_shape_explicit`), and file-reference resolution (`input_normalizer.py`) runs over the already-shaped content, so a re-wrapped `{ concept, content: { url: "pipelex-storage://…" } }` resolves identically to the compact `{ url }`. The envelope's `content` may itself be a scalar, a canonical file content, a list, or a structured object nesting file fields — the same top-down walk applies underneath.
|
|
178
178
|
|
|
@@ -198,7 +198,7 @@ Two consequences worth stating outright, because they are what the descriptor bu
|
|
|
198
198
|
|
|
199
199
|
A repeated reference to the **same source** within one preparation is uploaded once and rewritten consistently (within-preparation dedup by source identity). A caller value whose shape disagrees with the node — a scalar at an `object`, a non-array at a `list` — passes through for the run to reject; preparation never second-guesses the signature.
|
|
200
200
|
|
|
201
|
-
> **Why the descriptor, and why not the template.** Preparation used to read the *explicit inputs template
|
|
201
|
+
> **Why the descriptor, and why not the template.** Preparation used to read the *explicit inputs template*, served then by `POST /v1/build/inputs`, whose file signal was a rendered `{"url": …}` dict. That signal is a side effect of a field being **named** `url` or `*_url`, not of the field being an Image or a Document — so a text field named `url` was read off the caller's disk and uploaded, and an **optional** nested file field, which the required-only template never rendered, was invisible and travelled to the runner as a literal path. Both were live misclassifications. The descriptor states the kind instead of implying it, and states it at every depth, so both edges fall out correctly rather than needing special cases. It costs the same one round trip, it is the standard's own artifact rather than a presentation of it, and it is what `@pipelex/mthds-form`, `pipelex-app`, `mthds-ui` and `pipelex-mcp` already derive from. The template remains what it always was — a fill-in scaffold for a person or an agent — and is projected from this same descriptor, client-side, by `renderInputsTemplate`.
|
|
202
202
|
|
|
203
203
|
### Pass-through rules
|
|
204
204
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pipelex/sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.30.0",
|
|
4
4
|
"description": "TypeScript SDK for the Pipelex hosted API — execute methods, manage runs, and call the product surface.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
"vitest": "^4.0.18"
|
|
71
71
|
},
|
|
72
72
|
"dependencies": {
|
|
73
|
-
"mthds": "^0.
|
|
73
|
+
"mthds": "^0.30.0",
|
|
74
74
|
"smol-toml": "^1.6.0",
|
|
75
75
|
"undici": "^7.29.1"
|
|
76
76
|
}
|