v0.40.0
[v0.40.0] - 2026-07-19
Added
- Durable runs now persist token usage: the delivery executor writes a
tokens_usages.jsonresult artifact ({"tokens_usages": [...], "usage_assembly_error": null}) alongsideworking_memory.json, themain_stuff.*renders, and the graph outputs. The records use the client-facingTokensUsageRecordwire shape — the same shape the/executeresponse carries onpipe_output.tokens_usages— so a client polling a durable run's result files reads costs the same way a sync/executecaller does. The artifact is written unconditionally: a run with usage assembly off yields explicit nulls, distinguishable from a pre-artifact run (file absent). TokensUsageRecord— a deliberate client wire shape for token usage (pipelex/reporting/usage_records.py). One flat record per inference call:model_type,inference_model_name,inference_model_id,pipe_code,job_category,unit_job_id,nb_tokens_by_category(raw provider counts), computed USDcost(nullwhen the model has no rate table), and ISOstarted_at/completed_at. Enum-ish fields are open string sets on the wire, so runtime enum churn is non-breaking for clients.compute_tokens_usage_costreuses the existing cost engine (model_cost_per_token+ the cached/non-cached split), so the wirecostequals the CLI cost table's total for the same call. Documented in TokensUsage Wire Records.
Changed
- Breaking:
tokens_usagesrecords on client surfaces are nowTokensUsageRecordwire records, not dumps of the internal usage models. Both the/executeresponse (pipe_output.tokens_usages, via the newapply_tokens_usage_wire_shapehelper API servers apply to the response dump) and the durabletokens_usages.jsonartifact stop leaking runtime internals:job_metadata(with itsuser_id,session_id,request_id,pipe_run_id,otel_context,trace_context,content_generation_job_id,pipeline_run_id) and theunit_costsrate table no longer cross the wire — the keptJobMetadatafields (pipe_code, job-kind enums, timing) are flattened onto the record andcostis computed server-side. Null semantics unchanged (null= assembly off,[]= no inference). Internal crossings (runtime-bridge payloads, Temporal transport, the usage-event telemetry stream) keep full-fidelity records, untouched.
Fixed
- Validation errors stay domain-qualified: every raise site that names a
pipe_codenow also carriesdomain_code. The presentation chain (VS Code extension + mthds-ui) identifies pipes by full pipe ref (domain_code.pipe_code); a handful ofPipeValidationErrorraise sites (PipeLLM static input checks, PipeStructure input-mismatch, the pipe sorter's circular-dependency error) omitteddomain_code, degrading node decorations and click-to-navigate for those errors in multi-domain bundles. The sorter gains adomain_codeparameter threaded from the bundle spec's domain. - Hosted PipeFunc dry runs now honor output multiplicity. In sandbox-hosted mode a PipeFunc with a multiplicity output (e.g.
Foo[]) mocked a single scalar item because the function annotation is unavailable in-process; downstream pipes expecting a list (e.g.batch_over) then failed the dry-run//validateof a perfectly valid method. The mock now takes its shape from the declared output multiplicity. get_optional_config()honors its non-raising contract before any hub exists. It used to raiseRuntimeError: PipelexHub is not initializedwhen no hub had been created at all, which broke the documented safe pre-boot path — e.g. constructing aPipeFuncin an isolated unit test crashed instead of defaulting to thedirectexecution mode.- PipeFunc transport hardening: the wire contract now rejects a non-finite
timeout_seconds(float("inf")used to disable the runaway-code guard entirely), and the transported executor removes its materialized source workdir on every path (success, timeout, failure) instead of leaking a temp directory per invocation, pruning thesys.pathentries it inserted for that workdir in the same cleanup so dead entries can't accumulate (or be hijacked by a recreated path) in a reused process. - Error reference pages generated for the PipeFunc transport errors (
PipeFuncTransportError,PipeFuncExecutionError,DuplicatePipeFuncExecutorError,UnknownPipeFuncExecutionModeError) — theirtype_uris previously dereferenced to 404s.
What's Changed
- ci-cd: move tests-full + dependency-canary off Azure (shard the gate) by @thomashebrard in #1055
- fix: carry domain_code on every PipeValidationError that names a pipe_code by @lchoquel in #1057
- Fix PR #1052 review findings: PipeFunc transport hardening + review follow-ups by @lchoquel in #1056
- feat(delivery): persist token usage as a tokens_usages.json result artifact by @lchoquel in #1058
- Release v0.40.0 by @lchoquel in #1059
Full Changelog: v0.39.2...v0.40.0