Skip to content

v0.43.0

Choose a tag to compare

@github-actions github-actions released this 13 Oct 02:55
· 90 commits to main since this release
898b33d

@pipelex/sdk on npm

Added

  • A method's saved examples: createMethodExample, listMethodExamples, iterateMethodExamples, getMethodExample, updateMethodExample, recordMethodExampleLatestRun and deleteMethodExample read and write the named sets of inputs saved on a method, on the hosted API's /v1/methods/{id}/examples routes, with the MethodExample type and its input types, MethodExamplePage and ListMethodExamplesQuery. An edit of the inputs raises input_revision and clears latest_run_id; the list is paged oldest first, and iterateMethodExamples follows its cursor through the loop the other iterators share. An example id that is empty, . or .., a create without its name or inputs or whose run_id is given but empty (a null one reads as not given and is not sent), an edit naming neither name nor inputs, and a latest-run write without a run id or a positive integer revision are a RequestArgumentError before any request, a method id iterateMethodExamples cannot take one at the call itself, and every example the client hands back, the page rows and the verdict's included, is checked against the fields the Python SDK's model requires, with the strict types it holds them to, latest_run_id among them, one breaking them being an ApiResponseError (docs/method-examples.md).
  • The latest-run verdict: recordMethodExampleLatestRun records a run against the revision whose inputs it used and answers a MethodExampleLatestRunResult discriminated on outcome (MethodExampleLatestRunOutcome), recorded or stale, each arm carrying the example as it stands, so a run that outlasted an edit of the inputs is a verdict to branch on rather than a thrown error.
  • Exact integers, parseExactJson, stringifyExactJson and ExactJsonUnsupportedError: an integer past Number.MAX_SAFE_INTEGER in an example's inputs, which another client may have saved, reads as a bigint holding its exact digits on every example route, and every request body is written with a bigint as those digits, so such inputs go back unchanged to updateMethodExample or as a run's inputs instead of rounded; a float with no fractional part, 3.0, still reads as 3, so inputs holding one sent back unchanged to updateMethodExample raise the revision, since the platform compares inputs as canonical JSON. Both functions are exported, for a caller showing such data as JSON text, which JSON.stringify refuses for a bigint. On a runtime whose JSON.parse hands a reviver no source text, the reader refuses such an integer with ExactJsonUnsupportedError, which the client reports as an ApiResponseError for an answer it cannot read, rather than round it (docs/exact-integers.md).

Changed

  • A run's inputs and outputs keep integers past Number.MAX_SAFE_INTEGER exact (Breaking): getRunDetail's inputs, a completed run's results as getRunResult, waitForResult and startAndWaitForResult answer them (main_stuff, working_memory, graph_spec and every other field of the answer), and the answer of execute read such an integer as a bigint holding its exact digits instead of a rounded double, so inputs or an output passed back to start, or saved as an example's inputs, keep every digit. graph_spec is read exactly too, so a graph handed to a renderer can now carry a bigint. JSON.stringify throws on a bigint, so code showing such data as JSON text writes it with stringifyExactJson; the pipelex-sdk command prints it with its digits. The run status read and the run history read as before (docs/exact-integers.md).

Fixed

  • An id a route puts in its path is refused when the URL would resolve it: a method id given to getMethod, writeDraft, renameMethod, publishMethod, listMethodVersions, getMethodVersion or deleteMethod, a run id given to getRunStatus, getRunResult, getRunDetail or updateRun, an organization id given to renameOrganization and an API key id given to revokePipelexApiKey or rotatePipelexApiKey that is empty, . or .. is now a RequestArgumentError before any request, as is one that is not a string and one holding a lone surrogate, for which encodeURIComponent threw a bare URIError. encodeURIComponent leaves the dot alone, so . and .. reached the URL as dot segments, which the URL resolves before the request leaves: getRunDetail("..") read GET /v1/, deleteMethod(".") sent DELETE /v1/methods/, and an empty id addressed the route above it, getRunDetail("") sending GET /v1/runs/. Every one of these ids now goes through one guard.
  • getMethodVersion refuses every version it cannot take with RequestArgumentError: a version that is not a number is named by its type in the refusal, where one with no prototype, Object.create(null), made the refusal itself throw a TypeError.
  • A request body JSON cannot carry is the caller's argument, not a network failure: a body holding a cycle, or a bigint, was refused by JSON.stringify inside the request and thrown as ApiUnreachableError, with runMayHaveStarted true on start and execute, though nothing had been sent. The body is now written before the request is made, a bigint as its exact digits, and one that cannot be written is a RequestArgumentError with the failure as its cause.
  • A bigint in a request body is sent as its digits under a BigInt.prototype.toJSON polyfill: with the common polyfill BigInt.prototype.toJSON = function () { return this.toString(); } installed, JSON.stringify wrote a bigint in a request body as a quoted string, so the platform received text where the caller sent a number. Every request body is now written by stringifyExactJson in one JSON.stringify call whose replacer writes each bigint as its exact digits, the polyfill passed over, so each getter and toJSON in the body still runs once and an error one of them throws reaches the RequestArgumentError as its cause, never retried (docs/exact-integers.md).

pipelex-sdk on PyPI

Added

  • A method's saved examples: create_method_example, list_method_examples, iterate_method_examples, get_method_example, update_method_example, record_method_example_latest_run and delete_method_example read and write the named sets of inputs saved on a method, on the hosted API's /v1/methods/{id}/examples routes, with the MethodExample and MethodExamplePage models; the fields of the writes are keyword-only arguments. An edit of the inputs raises input_revision and clears latest_run_id; the list is paged oldest first, and iterate_method_examples follows its cursor through the loop the other iterators share. An example id that is empty, . or .., a create whose name or inputs is None 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 raise RequestArgumentError before any request, and a method id iterate_method_examples cannot take raises it at the call itself. MethodExample reads its fields strictly, as @pipelex/sdk checks them: latest_run_id is required, None when there is no latest run, no field is coerced from another type (an input_revision of "2", True or 2.0 is no revision), and input_revision lies within 2^53 - 1 either way, so an example breaking a field raises the ApiResponseError of an answer the SDK cannot read, as @pipelex/sdk refuses it.
  • The latest-run verdict: record_method_example_latest_run records a run against the revision whose inputs it used and answers a MethodExampleLatestRunResult discriminated on outcome (MethodExampleLatestRunOutcome), MethodExampleLatestRunRecorded or MethodExampleLatestRunStale, each carrying the example as it stands, so a run that outlasted an edit of the inputs is a verdict to branch on rather than a raised error; an answer off the union raises the ApiResponseError of an answer the SDK cannot read.

Changed

  • next_cursor is required on every page model (Breaking): MethodPage, MethodVersionPage and RunPage declared next_cursor: str | None = None, so a page answer without the key read as the last page and iterate_methods and iterate_runs stopped early without a word, where @pipelex/sdk refuses such a page. The field is now str | None with no default, on the new MethodExamplePage too: the platform always sends it, and a page without it raises the ApiResponseError of an answer the SDK cannot read. Code that builds a page model by hand passes next_cursor explicitly.

Fixed

  • An id a route puts in its path is refused when the URL would resolve it: a method id given to get_method, write_draft, rename_method, publish_method, list_method_versions, get_method_version or delete_method, a run id given to get_run_status, get_run_result, get_run_detail or update_run, an organization id given to rename_organization and an API key id given to revoke_pipelex_api_key or rotate_pipelex_api_key that is empty, . or .. now raises RequestArgumentError before any request, as does one that is not a str and one holding a lone surrogate, for which quote raised a bare UnicodeEncodeError. quote leaves the dot alone, so . and .. reached the URL as dot segments, which httpx resolves before the request leaves: get_run_detail("..") sent GET /v1, delete_method(".") sent DELETE /v1/methods, and an empty id addressed the route above it, get_run_detail("") sending GET /v1/runs/. Every one of these ids now goes through one guard, whose refusal names what it got: got None. for a None id, and the type's name for any other value that is not a str.