feat(cli): add --segments to the commands that accept it - #17
Merged
Conversation
segments is the only structured parameter the API takes, so it was skipped when the CLI was written. Both SDKs accept it; neither CLI exposed it. The flag takes inline JSON, @file, or @- for stdin — the curl / gh / aws convention. Validation is shape-only: parseable JSON, a non-empty array of objects, required fields present with the right types. The server's semantic rules (first segment at 0, minimum spacing, the label enum, item caps) are left to the API's 422, since a copy of them here would drift. Music commands (text-to-music, video-to-music) take {start, prompt, label?}; SFX commands (video-to-sfx, video-to-sound, video-to-video-sound) take {start, end, prompt}. Passing one shape to a command that takes the other is the predictable mistake, so errors name the expected shape and the keys that were actually given. Keys belonging to neither shape are forwarded untouched, so a field added to the API needs no CLI release. video-to-video-sfx is the sixth segment-capable endpoint in the SDK but has no CLI command yet, so only five commands gained the flag here.
Aligns the Python messages with the Node CLI, which already pointed at the
element that failed. A segments array is typically three or four items, so
naming the index saves the reader counting:
video-to-sfx segments take {start, end, prompt} — element 2 is not an object
video-to-sfx segments take {start, end, prompt} — "prompt" must be a string (element 1)
Indices are 0-based, matching Node. The shape mismatch message keeps its
no-index form ("got an object with keys ...") in both CLIs, since that is a
whole-payload mistake rather than one bad element.
Also renames the stdin source in parse errors from "standard input" to
"stdin", again matching Node.
The non-empty-array error keeps naming the expected shape, which Node's does
not — a deliberate difference, not an oversight.
Sapient docs evalsWaiting for the staging docs URL before running evals. Sapient will start the selected PR evals automatically when GitHub reports a successful docs deployment for this PR. This usually happens within 15 minutes. Commit: |
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 join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
segmentsis the only structured parameter in the API — every other CLI flag is a scalar — so it was skipped when the CLI was first written. Both SDKs have accepted it all along; neither CLI exposed it. This adds it.Surface
A value starting with
@is a source to read from;@-is stdin. Anything else is parsed as JSON directly. This follows the curl / gh / aws convention for structured flags.Commands that gain the flag, matching what each endpoint actually accepts:
{start, prompt, label?}—text-to-music,video-to-music{start, end, prompt}—video-to-sfx,video-to-sound,video-to-video-soundvideo-to-video-musicandtext-to-sfxdo not take segments.video-to-video-sfxdoes in the SDK, but has never been wired up as a CLI command — adding a command is a different change, so it is out of scope here.Validation is shape-only, on purpose
The CLI checks that the value parses, is a non-empty array, and that each element has the required fields with the right types. It does not replicate the server's semantic rules — first segment at
start: 0, minimum spacing, thelabelenum, distance from the end, item caps. Those live server-side, and a CLI copy would drift the moment the backend changes. The API's 422 stays the authority.Unknown keys pass through untouched so a future API field needs no CLI release. The one exception is a key belonging to the other segment shape (
endon music,labelon SFX): that is the predictable mistake this design invites — pointing SFX-shaped segments at a music command or the reverse — so it is rejected with a message naming the expected shape:Cross-CLI parity
The Node and Python CLIs were implemented against one shared contract and their user-visible behaviour was compared by running both. The shape-mismatch, wrong-type, and stdin-path errors are byte-identical, indices are 0-based in both. The only difference left is the wrapper wording on a JSON parse failure, where the tail is the runtime's own parser message (V8 vs CPython) and cannot be made identical anyway.
Tests
64 tests pass in
sonilo-cli— covering inline JSON,@file,@-, malformed JSON, non-lists, empty lists, both cross-shape directions, unknown-key passthrough, and that omitting the flag sends nosegmentsfield at all. The index-naming tests put the fault at index 2 and index 1 of a multi-element array, so an implementation that hardcoded0would fail them. The core SDK suite was re-run as a regression check: 192 pass, untouched.Release
sonilo-cligoes 0.3.0 → 0.4.0 in bothpyproject.tomland__init__.py— the latter feeds thex-sonilo-client-versionheader, so the two have to move together. The coresonilopackage is not bumped.