Conversation
…de worktrees Fingerprint leaves output:latest unpinned, drops iterations, adds cached_steps and per-device estimate, nullable download sizes, and notes the 409 must be server-side since dw_mcp is an httpx client. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… a sub-workflow is read by one resolver Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…or the caller's arguments Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…try when measured, plus each composed child Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…irst Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…sting's Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… than the listing Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
#85 stage 1: POST /api/validate answers with the run's plan. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…rve, by the run's own preparation Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… asks without blocking behind a job Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ould serve Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…queued it Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…n's plan, and a changed plan is a 409 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… and a 409 re-quotes Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
#85 stage 2: acknowledged_cost binds to the validated plan, a changed plan is a 409, jobs record the acknowledgement form, and the plan's cached_steps comes from the worker's step cache. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…the job tools name the acknowledgement field Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…not by probing the disk, and a composed child's digest is in the fingerprint Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…nd check, so a caller's 400 stays a 400 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ver read as the next probe's answer Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…a 409 without a measured estimate says so Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…d job says so Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
#85: the editor shows a validate answer's plan; a bound job says so. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Setting a result's file_base_name glued it onto the front of the <workflow id>-<step name>.<index> name it was meant to replace, with no separator, so the one field that exists to make a file name predictable produced a name the caller still had to read back out of the manifest. It now replaces that name. The derived name is what made two steps' files distinct, so a caller that sets the same one twice in a subfolder lands on output_file_path's existing -2 counter rather than overwriting. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Measures tools/list, the server instructions, the plugin skills and the fattest tool results against lem, and recommends where the tokens actually are: a get_guide with no section costs more than the whole 55-tool surface does on connect. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The dw/path-injection scan flagged one stat in resolve_sub_workflow: `os.path.isfile(candidate)` ran on `normpath(join(base_dir, name))` with nothing checking that the result was inside anything. Every caller does refuse the path afterwards - create_step_action validates the resolved path against its confinement, and the run's own error for an escaping reference is unchanged - so no caller read it. But resolution is not the enforcement point, and that left a real hole one frame up: realize.read_sub_workflow is handed the run's workflow_dir, which is None for a bare CLI run, and validate_workflow_path(path, None) normalizes without confining. An unconfined run therefore *read* a sub-workflow outside its catalog (the run then refused it, and realization digested it first). Containment now happens before the stat, against the root the candidate would be handed back with: the caller's confinement when it named one, else the catalog root the run itself would confine to. That second rule moved to workflow_sources.catalog_root so the resolver and workflow.catalog_root_dir cannot drift apart - the latter now delegates. Two details the surrounding design already insisted on, kept: - normpath before the validator, because validate_path refuses a '..' outright - so a climb that stays inside the root is collapsed first and '../models/x.json', the form every template uses, still resolves. - a climb out is a PathTraversalError, not a SubWorkflowNotFound: a refusal, not a name that was absent, which is the distinction the not-found message is careful about. Tests: the resolver refuses a climb out (confined and unconfined) and still resolves a climb to a sibling catalog folder; the unconfined read now answers None rather than the file's bytes, while the sibling climb stays readable. Co-Authored-By: Claude <noreply@anthropic.com>
A `video` argument given a file path or an `asset:` was loaded by fetch_video -> diffusers' load_video, which reads frames and drops the rate. pair_audio then had nothing to carry, so a 24 fps shot paired with a soundtrack was written at result.fps's default of 8: the same frames, three times long, with the track that was cut to fit ending a third of the way in, and nothing warned. `result.fps` rescued it for a caller who knew to reach for it. fetch_video now wraps the frames in a FrameList - a list subclass whose only addition is `.fps`, read from the container without decoding - so every consumer works unchanged while `getattr(video, "fps", None)`, the question AudioVideo, concat_videos and interpolate_frames already ask, gets a real answer. A file that states no rate stays a plain list; an unopenable one is not an error, since the frames are already read. This is the file-loading half of #84, which fixed the same silent three-times-long failure for a join. interpolate_frames gets it too: a `video` argument from a file now multiplies a real source rate rather than reporting none. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…passed
Two failures from the verification of the acknowledged-cost work.
1. The estimate did not scale with a fan-out list. A `cost` figure is
measured against a workflow's stored defaults, and `per_entry` - the
measured per-entry rate that re-prices it - is set on no template yet, so
`templates/minimax/dialogue-short` quoted 42.0 minutes for 2, 5 and 10
shots alike. The plan knew it would run 13 steps over 10 shots and quoted
the 5-shot figure anyway, and a bound acknowledgement then confirmed the
wrong number because the fingerprint matched.
The catalog total is now extrapolated linearly over a list whose length
the caller changed, with a new `basis` value - `derived` - saying it is an
estimate rather than a measurement. `catalog` now means what it says: the
stored total for a run whose lists are the ones it was measured with. A
measured `per_entry` still beats the extrapolation, `other_device` is not
extrapolated (re-pricing a figure from another accelerator would dress a
guess as arithmetic), and when more than one list changed there is nothing
honest to extrapolate along, so the figure is withheld (`unknown`) rather
than quoted for one of them.
2. A bare `acknowledged_cost=true` recorded `acknowledged: "none"`. The
MCP layer treated the boolean gate as its own and sent nothing, so the
server had nothing to record and a job queued on an acknowledgement was
indistinguishable from one that never passed a gate. It now sends `true`.
Also the two nits from the same report: the 409 message ends its sentence,
and it now carries the `{fingerprint, minutes, downloads}` shape to resend
rather than only the new fingerprint.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The measured assessment found that the tool schemas are not what costs an agent its context - single unbounded results are. One `get_guide` with no section is ~19.6k tokens, more in one call than the entire 55-tool surface costs to connect, and `get_schema` had no way to ask for less at all. Approved items 1-4 of that assessment. - `get_guide(name)` with no section answers the guide's index: its opening, its first section, and `sections`/`withheld` naming the rest, with a note saying how to fetch one. Nothing is unreachable, only unspent by accident. - `get_schema(section=...)` takes `steps`, `pipelines`, `tasks`, `result`, `variables` or `configuration` and answers that fragment plus `elsewhere`, which names the section holding each definition it still `$ref`s. Additive - the no-argument call is the whole schema, which is what the web UI reads. - `list_workflows()` with no filter cuts each entry to its summary and shape, because the whole catalog in full detail is ~6.8k tokens for a question that is really "which shape do I want". Asking with a `shape` returns the full entries. - The two narrative moves: `wait_for_job`'s measured H3 lead-in figures go to the minimax-h3 skill, which loads exactly when H3 is in play, and `get_memory`'s pinned-host-cache explanation to a new ACCELERATION.md section. Every rule stays in both descriptions. Result shapes change for the two no-argument calls - breaking-change for a scripted consumer. Also carries the #85 409-message and docstring edits in the files those two share. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ream diffusers' _write_audio takes two channels and nothing else, so pairing a mono voice track onto a picture died at the encode with a raw tensor shape after the run had already been paid for. as_audio_track now duplicates a single channel into two - lossless, and the ordinary case for dialogue - and emits a warning saying it did, so the change to what was handed in reaches the caller rather than only the log. The pair_audio docstring carries both that and the frame-rate rule #104 added elsewhere, which is #107's second item: get_task reads the implementation's own docstring, and that is where an author composing a task step looks first. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…nothing Two of the three one-liners from verifying #85/#104 (the third, the pair_audio docstring, is in the commit before this one): - the re-acknowledge object in the cost gate's 409 was built field by field in an f-string, so the common case - an inline workflow, which never has a measured estimate - printed 'minutes': None, which is not JSON a caller could paste back. The whole object goes through json.dumps now. - cached_steps: 0 cannot be told from 'probed and missed' out there, and the difference is that an unseeded workflow has no cache at all. validate now warns, once, at the point of use. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.
No description provided.