diff --git a/docs/MCP.md b/docs/MCP.md index 2be4b937..6dbe0d35 100644 --- a/docs/MCP.md +++ b/docs/MCP.md @@ -233,7 +233,7 @@ when no single workflow covers it. | Tool | Arguments | Purpose | | --- | --- | --- | -| `get_output_image(name, max_dimension=768, workspace=None)` | `name`, `max_dimension`, `workspace` | Look at a generated image, downscaled to `max_dimension` on its longest side. Returns the image plus a text part reporting `original_size`, `returned_size` and `bytes`, so a downscale is never silent. `workspace` names the workspace for this one call without switching the session to it - the same pin `run_workflow` takes, so a job run into another workspace stays reachable from the session that queued it | +| `get_output_image(name, max_dimension=768, workspace=None, crop=None)` | `name`, `max_dimension`, `workspace`, `crop` | Look at a generated image, downscaled to `max_dimension` on its longest side. Returns the image plus a text part reporting `original_size`, `returned_size` and `bytes`, so a downscale is never silent. `crop` is `[x, y, width, height]` in the original's pixels, cut before the downscale and reported back clamped - the way to see a region of a 2K still at 100%, where the whole would be shrunk past what a small element or a decode-tiling seam can be judged at. `workspace` names the workspace for this one call without switching the session to it - the same pin `run_workflow` takes, so a job run into another workspace stays reachable from the session that queued it | | `get_output_audio(name, workspace=None)` | `name`, `workspace` | Listen to a generated audio output, as base64. Unlike `get_output_image` there is no downscale - a clip whose base64 size would exceed the same 4MB budget is refused outright rather than cut or transcoded, since a truncated clip is a different, misleading answer rather than a smaller correct one (#204). Use `download_output` or the gallery `url` for a longer file, and `get_gallery_metadata` for its duration and sample rate without fetching the bytes at all. `workspace` names the workspace for this one call without switching the session to it | | `get_output_text(name, max_characters=20000, workspace=None)` | `name`, `max_characters`, `workspace` | Read a text output — a prompt enhancement, or any step whose result is `text/plain` or JSON. Reports the file's real length and whether it was truncated. `workspace` names the workspace for this one call without switching the session to it - the same pin `run_workflow` takes, so a job run into another workspace stays reachable from the session that queued it | | `download_output(name, destination=None, overwrite=False, workspace=None)` | `name`, `destination`, `overwrite`, `workspace` | Save one output file to local disk, of any content type. `destination` may be a full path, a directory, or omitted to save under the output's own name in the current working directory; `~` expands and missing parent directories are created. `overwrite=True` is required to replace a file already at the resolved path. Over a `dw.serve --mcp` endpoint the file lands on the server, so the destination is confined to that workspace and a relative one is joined onto it. Returns nothing to the conversation but where the file landed — unlike the other media tools, the point is a file on disk, not a payload in context. Writes on the machine running the MCP server - over `dw.serve --mcp` that is the GPU box. A write that fails there (a path that exists only on the client, for instance) comes back as an error naming the server-side write and the client-side alternatives, not as an anonymous tool failure. `workspace` names the workspace for this one call without switching the session to it - the same pin `run_workflow` takes, so a job run into another workspace stays reachable from the session that queued it | diff --git a/docs/WORKFLOW_GUIDE.md b/docs/WORKFLOW_GUIDE.md index 29d80af7..924045b5 100644 --- a/docs/WORKFLOW_GUIDE.md +++ b/docs/WORKFLOW_GUIDE.md @@ -283,6 +283,10 @@ for existence. - `asset:` — `asset:name` is a file in the asset library. Rooted at the library and confined to it, never resolved relative to the workflow file; a path that escapes the library is rejected. `upload_asset` returns one of these names. + One name, three places it can sit: a bare string (`"image": "asset:x.png"`), + an element of a list, or the `location` of a media dict + (`{"location": "asset:x.png"}`, with or without `media_type`) - all resolve + to the same file. - `output:` — `output://` is a file an earlier run wrote, under the output root and confined to it. `latest` in the run-id position picks the newest run that holds that file. A run id is not stable against @@ -727,7 +731,12 @@ longer than that is truncated with an ellipsis in every listing. Declare `shape`, `traits` or `summary` at the top level only when derivation gets it wrong; a declaration that merely repeats the derivation is noise that rots when the rules change, and the repo's catalog tests refuse it. `cost` is -never derived — leave it absent until a run has been measured. +never derived — leave it absent until a run has been measured. That makes it +the catalog's verified marker as well: an entry carrying `cost` has been run +to completion on the device it names, and one without has only been authored +— its description may still say what it has not been able to check (VRAM at +a size, whether a format carries what the pipeline returns), and the first +run is the one that finds out. `cost_drivers` is the other half of saying what a workflow costs, and it *is* for derivation: the variables that move the wall clock — a frame count, a diff --git a/docs/proposals/agent-catalog-legibility-complete.md b/docs/proposals/agent-catalog-legibility-complete.md index d9512afe..9843d81b 100644 --- a/docs/proposals/agent-catalog-legibility-complete.md +++ b/docs/proposals/agent-catalog-legibility-complete.md @@ -517,7 +517,7 @@ starts from the record rather than the intent. Updated as work lands. | 9 composition rules | done (plan 2, task 6) | spec §2.3 | the cartesian rule and the one-step-per-pair form are stated in the authoring section, the general case of `scripted-dialogue-and-tts-complete.md`'s reasoning | | 10 save-time metadata | done (task 6) | spec §1.6 | derived and returned on save; empty summary warns, never rejects | | Part 3 constraint | carried | spec "Principle" | derivation reads structure, never model family | -| Part 4 packaging | done: Channel A for the generic item (2026-09-07), Channel B for model families (2026-09-08) | `WORKFLOW_GUIDE.md` authoring section; `plugins/dw/`, `.claude-plugin/marketplace.json`, `.claude/skills/model-family-onboarding` | the spoon-set drill (cold session, PR #48 merged) planned a shared seed for "identical but for colour", which draws a different object per prompt; `### Keeping a set consistent` now says which of style, object or character consistency wants prompts, an edit pass or a reference, and `templates/consistent-set.json` (declared `image-set`: derivation says `image-edit`) is the generate-then-edit shape on FLUX.1 Kontext, whose one pipeline both draws and edits; measured on lem 2026-09-07 at 11.5 warm minutes (2.2 for the base, 3.1 per edit, sequential offload) and the four mugs came out identical but for colour. A FLUX.2 draft found that the HF remote text encoder every FLUX.2 entry names now answers with an HTML page (broken on lem since 2026-08-26); `remote.py` now says so instead of raising an unpickling error, and both FLUX.2 entries load the repo's own 4-bit text encoder under model offload instead. The FLUX.2 text encoder is declared as its own component pinned to the CPU, because BitsAndBytes materializes on the accelerator and the two 4-bit models do not fit at load; the `flash_hub` backend went too, since it needs the `kernels` package no install has. models/flux2-dev measured at 3.3 warm minutes on lem. The Krea edit template moved to FLUX.1 Kontext for the same reason, and a catalog test now refuses `trust_remote_code` and `custom_pipeline` in any bundled entry or packaged builtin, so nothing dw ships asks an operator to lower `--trust-workflows`. The Florence-2 and Phi-3.5 builtins went with it: the `text_generation` task had replaced both, and `describe-and-regenerate` now composes it twice. `### Remote code is refused by default` came out of the same run: the first draft used the Krea edit template's `custom_pipeline`, which a server without `--trust-workflows` refuses at load. Superseded by plugin tasks 1-5 below: `templates/minimax/README.md` and `ltx2/README.md` are the sources the family skills derive from and link back to, so that knowledge is reached through the plugin rather than a third channel. Catalog repair task 1: the latent handoff a two-stage flow needs is proven by test (tests/test_result.py::TestLatentHandoff), no engine change. Catalog repair task 2: two-stage.json is the three-move flow (8 sigmas at 768x448, 2x latent upsample, renoise + 3 stage-two sigmas at 1536x896, audio latents carried); latents pass by name; a test holds noise_scale to STAGE_2_DISTILLED_SIGMA_VALUES[0]. Cost and the sharpness comparison await the lem run (task 7). Catalog repair task 3: the six prompts/ltx2 captions are rewritten to the trained format (one paragraph, 150-220 words, shot type/camera motion/viewpoint in prose, sound interleaved; the two I2V ones describe only what changes), intended_model ltx-2.5, four summaries say LTX-2.5; tests/test_ltx_prompt_library.py holds the shape. Catalog repair task 4: h3_context_ir names its two source guides, writes N/A for silent audio fields, numbers