Release/v0.14.0#64
Conversation
…#62) * feat: generate the typed clients from the bundles via pipelex codegen Delete the hand-written output models: pipelex codegen projects each method's concepts into piper/generated/<method>/models.py (stamped, locked by a sibling codegen.lock); the examples keep only the bundle path, pipe code, and the parse() narrower. generate-image now parses into the generated built-in Image model. New make codegen (regen, write-if-changed) + make codegen-check (offline drift check) targets — the pipelex CLI is not a dependency, point the PIPELEX make variable at an install that ships codegen; CI wiring is release-gated on a published pipelex. Adds inputs.template.json scaffolds beside each bundle, offline smoke tests for the generated clients, and docs/codegen.md. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EaRwjPbPsan4rCeyWirKpp * fix(devx): Checkpoint C review — ship codegen.lock in wheel + lockstep comments Cold-review triage: package each codegen.lock as package data so the offline drift check also works against an installed copy, and cross-reference the three places the method list is enumerated (piper/methods/*, pyproject packages, the Makefile codegen targets). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EaRwjPbPsan4rCeyWirKpp * chore(codegen): regenerate typed clients — pinned native definitions + flattened Image Regenerated with the codegen engine after the native-materialization change: Image now emits width/height integer fields instead of the interim dict-with-imprecision size, and native field descriptions come from the pinned normative definitions (storage-neutral url wording, described Text). Crate fingerprints and stamps updated accordingly; codegen-check green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs: changelog — call out the generated Image shape change (width/height) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * chore(Makefile): update PIPELEX_RUN to streamline codegen invocations * simplify * feat(cli): update execution modes to use a single --mode option; remove --detach flag * feat: remove legacy file input and runner modules; introduce new test suite for document input handling * feat: introduce detached CLI mode for durable runs - Added `piper.detached` package with CLI commands for starting and managing durable runs. - Implemented commands: `extract-entities`, `summarize-pdf`, `generate-image`, `wait`, `status`, and `result`. - Created shared input handling functions in `piper.inputs` for text and document inputs. - Enhanced error presentation in `piper.errors` to provide mode-specific hints. - Updated tests to cover the new detached mode and ensure symmetry across CLI modes. - Refactored existing tests to align with the new structure and added new unit tests for input handling. * feat: enhance CLI demos to run with zero arguments using built-in samples - Updated all demo commands to utilize bundled sample inputs when no arguments are provided, ensuring a working result on the first command execution. - Introduced a `sample` parameter in `read_text_input()` to facilitate this feature. - Enhanced error handling to surface detailed API error messages instead of generic httpx errors, improving user feedback. - Refactored execution modes into self-contained units, removing the previous shared dispatch structure for clarity and maintainability. - Updated documentation to reflect changes in execution modes and sample usage. - Added tests to verify that demos correctly fall back to sample inputs when no user input is provided. --------- Co-authored-by: Louis Choquel <8851983+lchoquel@users.noreply.github.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* feat: generate the typed clients from the bundles via pipelex codegen Delete the hand-written output models: pipelex codegen projects each method's concepts into piper/generated/<method>/models.py (stamped, locked by a sibling codegen.lock); the examples keep only the bundle path, pipe code, and the parse() narrower. generate-image now parses into the generated built-in Image model. New make codegen (regen, write-if-changed) + make codegen-check (offline drift check) targets — the pipelex CLI is not a dependency, point the PIPELEX make variable at an install that ships codegen; CI wiring is release-gated on a published pipelex. Adds inputs.template.json scaffolds beside each bundle, offline smoke tests for the generated clients, and docs/codegen.md. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EaRwjPbPsan4rCeyWirKpp * fix(devx): Checkpoint C review — ship codegen.lock in wheel + lockstep comments Cold-review triage: package each codegen.lock as package data so the offline drift check also works against an installed copy, and cross-reference the three places the method list is enumerated (piper/methods/*, pyproject packages, the Makefile codegen targets). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EaRwjPbPsan4rCeyWirKpp * chore(codegen): regenerate typed clients — pinned native definitions + flattened Image Regenerated with the codegen engine after the native-materialization change: Image now emits width/height integer fields instead of the interim dict-with-imprecision size, and native field descriptions come from the pinned normative definitions (storage-neutral url wording, described Text). Crate fingerprints and stamps updated accordingly; codegen-check green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs: changelog — call out the generated Image shape change (width/height) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * chore(Makefile): update PIPELEX_RUN to streamline codegen invocations * simplify * feat(cli): update execution modes to use a single --mode option; remove --detach flag * feat: remove legacy file input and runner modules; introduce new test suite for document input handling * feat: introduce detached CLI mode for durable runs - Added `piper.detached` package with CLI commands for starting and managing durable runs. - Implemented commands: `extract-entities`, `summarize-pdf`, `generate-image`, `wait`, `status`, and `result`. - Created shared input handling functions in `piper.inputs` for text and document inputs. - Enhanced error presentation in `piper.errors` to provide mode-specific hints. - Updated tests to cover the new detached mode and ensure symmetry across CLI modes. - Refactored existing tests to align with the new structure and added new unit tests for input handling. * feat: enhance CLI demos to run with zero arguments using built-in samples - Updated all demo commands to utilize bundled sample inputs when no arguments are provided, ensuring a working result on the first command execution. - Introduced a `sample` parameter in `read_text_input()` to facilitate this feature. - Enhanced error handling to surface detailed API error messages instead of generic httpx errors, improving user feedback. - Refactored execution modes into self-contained units, removing the previous shared dispatch structure for clarity and maintainability. - Updated documentation to reflect changes in execution modes and sample usage. - Added tests to verify that demos correctly fall back to sample inputs when no user input is provided. * fix: address PR #62 review feedback for zero-argument CLI demos Guards bootstrap against package names that collide with the piper placeholder, and refines sample-input/error handling in the attended CLI mode with corresponding test coverage updates. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AA5fmhTMLRLTJgVmCsW6da * fix: bootstrap rewrites Makefile codegen paths and docs The bootstrap script's rewrite set never included the Makefile, so the codegen targets kept pointing at piper/generated and piper/methods after a rename, breaking make codegen / make codegen-check on bootstrapped projects. Same gap for the docs under docs/, which went stale. Both are now in the rewrite set (the generic context-aware token pass handles their path/command forms), SKILL.md lists them, and a non-dry-run test asserts the rewritten paths. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AA5fmhTMLRLTJgVmCsW6da --------- Co-authored-by: Louis Choquel <8851983+lchoquel@users.noreply.github.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…structured CLI modes Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AA5fmhTMLRLTJgVmCsW6da
Greptile SummaryThis PR reorganizes the CLI around three explicit execution modes and adds generated clients. The main changes are:
Confidence Score: 4/5The installed zero-argument PDF demo needs a packaging fix before merging. Source checkouts contain the default invoice, so local runs work. Built wheels do not ship that file at the path used by piper/inputs.py and pyproject.toml
What T-Rex did
Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
CLI[piper CLI] --> B[blocking]
CLI --> A[attended]
CLI --> D[detached]
B --> E[client.execute]
A --> S[client.start]
S --> W[client.wait_for_result]
D --> DS[client.start]
D --> R[status / result / wait]
E --> O[Generated-model JSON]
W --> O
DS --> ID[Run ID]
R --> O
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
CLI[piper CLI] --> B[blocking]
CLI --> A[attended]
CLI --> D[detached]
B --> E[client.execute]
A --> S[client.start]
S --> W[client.wait_for_result]
D --> DS[client.start]
D --> R[status / result / wait]
E --> O[Generated-model JSON]
W --> O
DS --> ID[Run ID]
R --> O
Prompt To Fix All With AIFix the following 1 code review issue. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 1
piper/inputs.py:33
**Bundled Sample Is Missing From Wheels**
When `summarize-pdf` runs without an argument from an installed wheel, this path resolves to `site-packages/samples/sample-invoice.pdf`. The sample remains outside the `piper` package and is not declared as package data, so the new zero-argument path raises `FileNotFoundError` instead of running the demo.
Reviews (1): Last reviewed commit: "Release v0.14.0: zero-arg demo fallbacks..." | Re-trigger Greptile |
| # Sample inputs — the zero-argument fallback for each demo (also the README's examples). | ||
| SAMPLE_ENTITIES_TEXT = "Alice from Acme met Bob on May 3rd, 2026." | ||
| SAMPLE_IMAGE_PROMPT = "a fox reading under a tree" | ||
| SAMPLE_INVOICE = Path(__file__).parent.parent / "samples" / "sample-invoice.pdf" |
There was a problem hiding this comment.
Bundled Sample Is Missing From Wheels
When summarize-pdf runs without an argument from an installed wheel, this path resolves to site-packages/samples/sample-invoice.pdf. The sample remains outside the piper package and is not declared as package data, so the new zero-argument path raises FileNotFoundError instead of running the demo.
Artifacts
Repro: Python harness that inspects the wheel and executes the installed document input path
- Contains supporting evidence from the run (text/x-python; charset=utf-8).
Repro: reusable wheel build and isolated-install runner
- Contains supporting evidence from the run (text/x-shellscript; charset=utf-8).
Stack trace captured during the T-Rex run
- Keeps the raw stack trace available without making the summary code-heavy.
Ran code and verified through T-Rex
Prompt To Fix With AI
This is a comment left during a code review.
Path: piper/inputs.py
Line: 33
Comment:
**Bundled Sample Is Missing From Wheels**
When `summarize-pdf` runs without an argument from an installed wheel, this path resolves to `site-packages/samples/sample-invoice.pdf`. The sample remains outside the `piper` package and is not declared as package data, so the new zero-argument path raises `FileNotFoundError` instead of running the demo.
How can I resolve this? If you propose a fix, please make it concise.
[v0.14.0] - 2026-07-15
Added
samples/sample-invoice.pdfforsummarize-pdf) and printing a notice to stderr, so stdout stays pipeable and a fresh clone shows a working result on the first command.read_text_input()gains asampleparameter and returns aTextInput(text, is_sample)..mthdsbundles intopiper/generated/viapipelex codegen, replacing hand-written models (generate-imagenow parses into the generatedImagemodel, replacing the hand-writtenGeneratedImage). Addedmake codegento regenerate clients and templates, andmake codegen-checkto verify offline (via hashing against eachcodegen.lock) that generated clients are up to date. Eachcodegen.lockships as package data, so the check also works against an installed (wheel) copy, not just a git checkout.docs/cli-architecture.md, describing the copy-paste CLI layout, anddocs/codegen.md, explaining the generated-models workflow.tests/unit/test_generated_clients.pyto verify generated modules import correctly, carry the stamp + lock, round-trip their serialization, and match the committed input templates to the CLI's inputs; andtests/unit/test_mode_symmetry.pyto guard against drift between CLI modes./bootstrapnow rejects package names that collide with the template'spiperplaceholder (e.g.piper_tools, which would corrupt intopiper_tools_toolsunder the pyproject transform).Changed
--mode,--detach, and thePIPELEX_EXECUTION_MODEenv var are gone — invoke the mode explicitly:piper blocking <demo>,piper attended <demo>, orpiper detached <demo>. The top-levelrunscommand moves under detached mode (piper detached status|result|wait <id>). There is no default mode anymore; the mode is explicit in every invocation, which is itself the lesson. The middle mode is namedattended, notdurable, because detached runs are durable too — the axis the names describe is who waits.Imagedimensions (Breaking): the generatedImagemodel now uses optional integerwidthandheightfields instead of an untypedsizedict, with native field descriptions sourced from the standard's pinned definitions. Regenerated all committed clients (stamps, locks, and fingerprints updated).piper/<mode>/cli.py) with its own commands, SDK lifecycle helper (execute_pipe/start_and_wait/start_pipe), and progress rendering; lifecycle code is no longer shared. Only mode-orthogonal code remains shared:piper/inputs.py(text/file inputs and document envelopes —piper/file_input.pyis merged into it) andpiper/errors.py, whose hints now name the mode groups (a blocking run that hits the ~30s cap points atpiper attended; an interrupted attended run points atpiper detached wait <id>).problem+jsonbody (title,detail, machineerror_type) instead of httpx's stringification, with hints pointing to the correct CLI mode based on error type (e.g.StartRequiresAsyncOrchestrationpoints atpiper blocking).extract-entities→ blocking,summarize-pdf→ attended,generate-image→ detached) for full matrix coverage.piper/generatedis excluded from ruff (reformatting generated files would trip the drift check) but remains fully type-checked.Fixed
pyproject.tomltransform:/bootstrapnow rewritespyproject.tomlusing generic, context-aware rules (quoted-exact and dotted/path positions) instead of per-key edits, preventing staleness as the package list changes, and correctly handles the multi-linepackagesarray with thepiper.generated.*subpackages, quoted package-data keys, and thepiper/generatedruff exclude.Removed
piper/runner.py, the central_dispatch()chain, and theExecutionModeenum, in favor of the self-contained mode CLIs;piper/cli.pyshrinks to aload_dotenvcallback plus threeadd_typercalls.piper/examples/layer: removed the per-demo wrapper modules; demo logic and inline model narrowing (Model.model_validate(main_stuff)) now live directly in the mode CLI files. Theparse()unit tests went with it (they only exercised pydantic'smodel_validate).piper/file_input.py: merged into the new sharedpiper/inputs.pymodule.🤖 Generated with Claude Code
https://claude.ai/code/session_01AA5fmhTMLRLTJgVmCsW6da