Repository navigation
Release v0.23.0 - #98
Merged
Merged
Conversation
`MthdsAPIClient` and the local `PipelexRunner` now take a method as `files`, the MTHDS standard's map of file entries, in place of `mthds_contents`, and the client can send a tree by hash: `VersionInfo` declares `blob_store`, the protocol models carry the blob routes' shapes, and `prepare_files` sends a tree inline when its encoded map is small or the runner keeps no blob store, otherwise uploading only the blobs `POST /blobs/missing` names. This is the breaking protocol change `pipelex-sdk`'s Python client builds on. Closes L-261015-bebfc9 Closes L-261016-b75856 Advances L-261012-989e43 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated description by cubic. --> --- ## Summary by cubic Replaces inline `mthds_contents` with `files`, the MTHDS standard's map of file entries, in `MthdsAPIClient` and the local `PipelexRunner`, and lets the client send a method tree by hash. `prepare_files` sends the tree inline when its encoded map is small or the runner keeps no blob store, otherwise uploading only the blobs the runner lacks and referencing every file by hash. This is a breaking protocol change that `pipelex-sdk`'s Python client builds on. - `VersionInfo` now reports `blob_store`; the blob routes' wire shapes are typed models. - Files are read and hashed off the event loop, an upload sends only its target's headers and never the API key, and a refused upload raises `BlobUploadError`. Closes L-261015-bebfc9 and L-261016-b75856; advances L-261012-989e43. <sup>Written for commit 2aa615e. Summary will update on new commits.</sup> <a href="https://cubic.dev/pr/mthds-ai/mthds-python/pull/95?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="View guided diff" src="https://www.cubic.dev/buttons/review-in-cubic-light.svg"></picture></a> <a href="https://www.cubic.dev/action/auto-fix/pr/mthds-ai/mthds-python/95?returnTo=https%3A%2F%2Fgithub.com%2Fmthds-ai%2Fmthds-python%2Fpull%2F95&source=description" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/turn-on-auto-fix-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/turn-on-auto-fix-light.svg"><img alt="Turn on auto-fix" src="https://www.cubic.dev/buttons/turn-on-auto-fix-light.svg"></picture></a> <!-- End of auto-generated description by cubic. --> --------- Co-authored-by: Claude Opus 5.5 <[email protected]>
An empty tree's refusal now carries what the listing kept out:
`list_method_tree` and `list_method_tree_at_root` raise
`EmptyMethodTreeError`, a `MethodTreeRefusedError` holding the root, the
excluded files and directories and their raw paths, so a caller listing
a directory for its nested packages, as pipelex does for a library
directory, learns them even when the directory's own tree is empty. The
refusal record stays the conformance corpus's `{"code": "empty_tree",
"names": []}`, so existing callers behave as before.
Closes L-261015-855658
Advances L-261012-989e43
🤖 Generated with [Claude Code](https://claude.com/claude-code)
<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
`list_method_tree` and `list_method_tree_at_root` now refuse a directory
whose own tree is empty with `EmptyMethodTreeError`, a
`MethodTreeRefusedError` that also carries the listing's `root`,
`excluded_files`, `excluded_directories`, and `raw_paths`. This lets a
caller listing a directory for its nested packages learn them even when
the directory holds nothing else. The refusal record stays the
conformance corpus's `{"code": "empty_tree", "names": []}`, so existing
callers catching `MethodTreeRefusedError` are unaffected; the lister
still never returns an empty tree.
Closes L-261015-855658, advances L-261012-989e43.
<sup>Written for commit bf3154b.
Summary will update on new commits.</sup>
<a
href="https://cubic.dev/pr/mthds-ai/mthds-python/pull/96?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="View guided diff"
src="https://www.cubic.dev/buttons/review-in-cubic-light.svg"></picture></a>
<a
href="https://www.cubic.dev/action/auto-fix/pr/mthds-ai/mthds-python/96?returnTo=https%3A%2F%2Fgithub.com%2Fmthds-ai%2Fmthds-python%2Fpull%2F96&source=description"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/turn-on-auto-fix-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/turn-on-auto-fix-light.svg"><img
alt="Turn on auto-fix"
src="https://www.cubic.dev/buttons/turn-on-auto-fix-light.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
Co-authored-by: Claude Opus 5.5 <[email protected]>
A file reference can now be resolved over a set of tree paths, from a holder or from the root, with `resolve_reference_in_paths`, and the URL context's steps are public as `url_path_of` and `percent_decode_url_path`, so a runtime holding only a tree's listing, or a bundle parsed from a content string, resolves by the standard's steps without its own copy. `resolve_reference` and the new entry point share one implementation, and every corpus reference probe runs through both. Closes L-261016-0b2e7e Advances L-261012-989e43 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated description by cubic. --> --- ## Summary by cubic Adds `resolve_reference_in_paths`, which runs the standard's file-reference resolution steps over a set of tree paths instead of a `MethodTree`, so a runtime holding only a tree listing, or a bundle parsed from a content string, can resolve references without the tree. With `holder=None` it resolves from the root, exactly as a reference written in a file at the root; `resolve_reference` and the new entry point share one implementation, and every corpus reference probe now runs through both. The URL context steps 1 and 3 are public as `url_path_of` and `percent_decode_url_path`, and `lexical_join` takes `holder=None` to join from the root. Closes L-261016-0b2e7e. Advances L-261012-989e43. **Notes for callers** - A refusal as not in the tree names no membership rule, which a set of paths does not record; only `resolve_reference` adds it. - A holder that is not one of the tree paths raises `ValueError`, for both entry points. <sup>Written for commit 9731079. Summary will update on new commits.</sup> <a href="https://cubic.dev/pr/mthds-ai/mthds-python/pull/97?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="View guided diff" src="https://www.cubic.dev/buttons/review-in-cubic-light.svg"></picture></a> <a href="https://www.cubic.dev/action/auto-fix/pr/mthds-ai/mthds-python/97?returnTo=https%3A%2F%2Fgithub.com%2Fmthds-ai%2Fmthds-python%2Fpull%2F97&source=description" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/turn-on-auto-fix-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/turn-on-auto-fix-light.svg"><img alt="Turn on auto-fix" src="https://www.cubic.dev/buttons/turn-on-auto-fix-light.svg"></picture></a> <!-- End of auto-generated description by cubic. --> --------- Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Release v0.23.0
Bumps version from
0.22.0to0.23.0. Promotesdev→main.Changelog
Added
MthdsAPIClient.missing_blobsandupload_blobcall the protocol's optional blob routes, typed byBlobRef,MissingBlobsRequest,MissingBlobsResult,MissingBlobandUploadTarget, andprepare_filesandprepare_files_from_contentsbuild a request'sfilesfrom a listed tree or from bytes at hand: inline when the map, written as compact JSON in UTF-8 so that Base64 counts as its encoded text, is at mostDEFAULT_INLINE_TREE_MAX_BYTES(256 KiB), or when the runner keeps no blob store, and otherwise uploading only the blobs the runner lacks and sending every file by hash. Files are read and hashed off the event loop, an upload carries exactly its target's headers and never the API key, and a refused one raisesBlobUploadError, whose URL keeps no userinfo, query or fragment.VersionInfo.blob_store: theversion()handshake reads whether the runner keeps a blob store, false when the runner does not say.EmptyMethodTreeError:list_method_treeandlist_method_tree_at_rootrefuse a directory whose own tree is empty with thisMethodTreeRefusedError, which also carries the listing'sroot,excluded_files,excluded_directoriesandraw_paths, so a caller that lists a directory to find the packages and repositories nested in it learns them even when the directory holds nothing but nested packages. The refusal's code staysempty_treeand its record stays the conformance corpus's, so a caller catchingMethodTreeRefusedErroris unaffected; its message now says when the root is itself a virtual environment.resolve_reference_in_pathsruns the standard's resolution steps, the same implementationresolve_referenceruns, in a set of tree paths rather than aMethodTree, for a runtime that holds only a tree's listing; withholder=Noneit resolves from the root a reference written in no file of the tree,is_one_file_treegives the one-file tree's refusal, and a refusal as not in the tree names no membership rule, which a set of paths does not record. Steps 1 and 3 in URL context are public asurl_path_ofandpercent_decode_url_path, which refuses asreference_invalid, naming the path, what step 3 refuses, andlexical_jointakesholder=Noneto join from the root.Changed
files(Breaking):MthdsAPIClient.execute,startandvalidate, theMTHDSProtocolinterface andPipelexRunnertake the method asfiles, a map from tree path to file entry typedMethodFiles, in place ofmthds_contents, and the protected_post_validateseam takesfilestoo; an empty map is refused before any request. A runner that still accepts inlinemthds_contentsreceives it throughextra, andPipelexRunnerwrites the map out as a directory forpipelex run bundleandpipelex validate bundle, refusing a hash entry.encode_file_entryandencode_file_mapreturnFileEntryvalues, astr, aBase64FileEntryor aHashFileEntry, instead of plain dictionaries, andpydantic_core.to_jsonwrites them in their wire form.🤖 Generated with Claude Code
Summary by cubic
Promotes
mthdsto v0.23.0, the breaking release in which a method travels as afilesmap of typed file entries instead of inlinemthds_contents, and the API client can send a tree by hash through the protocol's optional blob routes.Breaking changes
execute,start,validate,MTHDSProtocol, andPipelexRunnernow take the method asfiles; inlinemthds_contentsis only passed throughextra.encode_file_entryandencode_file_mapreturn typedFileEntryvalues instead of plain dictionaries.Added
prepare_filessends a tree inline when its compact JSON is at most 256 KiB or the runner keeps no blob store, otherwise uploading only the blobs the runner lacks and referencing each file by hash.VersionInfo.blob_storereports runner blob-store support; uploads never send the API key, and a refused upload raisesBlobUploadError.EmptyMethodTreeErrorcarries the root and what the listing kept out.resolve_reference_in_pathsresolves a reference over a set of tree paths, withurl_path_ofandpercent_decode_url_pathpublic.Written for commit 5140ba8. Summary will update on new commits.