Release v0.5.0
Release v0.5.0
Bumps version from 0.4.0 to 0.5.0.
Changelog
Added
-
Input preparation:
upload_fileandprepare_inputs(hosted upload capability). The Python counterpart of@pipelex/sdk'suploadFile/prepareInputs, in parity.client.upload_file(source, *, filename=None, content_type=None)uploads one local asset — a filesystem path (str/Path) or rawbytes— and returns anUploadRecord(uri,content_type,size,filename) assembled client-side.client.prepare_inputs(*, files, pipe_ref=None, inputs)resolves the target pipe's declared signature from the explicit inputs template, interprets the caller's compactinputstop-down against it (the file signal is the canonical Image/Document content shape — a{"url": …}dict — mirroring the runtime'sinput_normalizer), uploads the file-bearing values, and returnsPreparedInputs: a copy-on-write rewrite ofinputswith each asset reference replaced by canonical content carryingpipelex-storage://inurl, plus oneUploadRecordper prepared asset. HTTP(S) URLs and existingpipelex-storage://URIs pass through unchanged; data URLs and local/byte sources are uploaded; the same source referenced twice uploads once (dedup by source identity); all failures are raised before any run is created. Failures are typed per category:InvalidLocalSourceError,RejectedAssetError,UnsupportedUploadCapabilityError,UploadAuthenticationError,UploadTransportError(all extendInputPreparationError).prepare_inputstakes the method closure as inlinefiles; catalogmethod_idresolution and opt-inhttp(s)ingest are deferred and additive. Seedocs/input-preparation.md. -
build_inputsroute (POST /v1/build/inputs). Closes the/v1/build/*parity gap the Python SDK had —client.build_inputs(BuildInputsRequest)projects a pipe's declared inputs as a fill-in template, returning a 200 verdict discriminated onis_valid(BuildInputsValidReport|CrateInvalidReport); a no-verdict condition throwsApiResponseError. It is the signature sourceprepare_inputsreads (withexplicit=True). Models live inpipelex_sdk/build_models.py. -
Typed run usage:
RunResults.tokens_usages+RunResults.usage_assembly_error. The per-call usage records a run produces — token counts by category, the server-computedcostin USD, model name and id, the pipe that made the call, job-kind fields and timing, for LLM and img-gen/extract/search calls alike — are now first-class typed fields instead of ridingmodel_extra. Records validate into a newTokensUsageRecordmodel (pipelex_sdk/runs.py) mirroring the wire contract specified in the MTHDS protocol spec. Both paths populate the pair: the hosted durable path reads it offGET /v1/runs/{id}/results(which unpacks the runner'stokens_usages.jsonartifact), and the blocking fallback lifts the same pair out of the execute response's extension-openpipe_output— soresult.tokens_usagesreads the same regardless of which path ran.Note that the rate table (
unit_costs) no longer crosses the wire: a record now carries the computedcostfor the call instead, which isNonewhen the model has no rate table at all (own-GPU, mock, dry run) and0when a rate table priced it at zero. There is no run-level aggregate — sum the records.tokens_usagesisNonewhenever usage assembly produced no list (it was off, it broke, or the run was delivered before the artifact existed) and[]when assembly ran and no inference happened;usage_assembly_erroris the only field separating a broken assembly from an off one.TokensUsageRecordkeeps every field optional and is extension-open, so durable artifacts written before the contract shipped — relayed verbatim, never migrated — still parse:costandpipe_codecome backNone, and the legacyjob_metadata/unit_costssurvive inmodel_extra. Enum-ish fields (model_type,job_category,unit_job_id) are open sets typed as plainstr, so runtime enum churn stays non-breaking.
Changed
RunResults.pipe_outputis nowDictPipeOutputAbstract | None, wasdict[str, Any] | None(breaking). The blocking path already parsed the protocol model and then threw the types away with a.model_dump()round-trip; it now carries the parsed model straight through. Read the working memory as attributes —result.pipe_output.working_memory.root["out"].content— rather than nested dict keys. The durable path still leaves itNone.
🤖 Generated with Claude Code
Summary by cubic
Release v0.5.0 adds hosted input preparation (upload_file, prepare_inputs), introduces build_inputs for signature templates, and exposes typed run-usage records on results. It also changes RunResults.pipe_output to a typed model. Adds a WIP doc with deferred review findings (no code changes).
-
New Features
- Input preparation:
client.upload_file(source, filename?, content_type?)andclient.prepare_inputs(files, pipe_ref?, inputs)rewrite file inputs topipelex-storage://URLs, pass through http(s)/existing URIs, dedup repeated sources, and raise clear typed errors. Mirrors@pipelex/sdk. build_inputssupport:client.build_inputs(BuildInputsRequest)returns the explicit inputs template with anis_validverdict; used byprepare_inputs.- Typed run usage:
RunResults.tokens_usagesandusage_assembly_errorvalidate intoTokensUsageRecordand are available on both hosted and blocking paths; each record includes per-call token counts and computed USDcost.
- Input preparation:
-
Migration
RunResults.pipe_outputis nowDictPipeOutputAbstract | None(wasdict). Access working memory via attributes, e.g.result.pipe_output.working_memory.root["out"].content.